企业进行网站建设的方式有,工作汇报总结怎么写,湛江做网站seo,佛山 网络推广用成员函数重载实现is_default_constructible
首先介绍一个C标准库提供的可变参类模板std::is_default_constructible。这个类模板的主要功能是判断一个类的对象是否能被默认构造#xff08;所谓默认构造#xff0c;就是构造一个类对象时#xff0c;不需要给该类的构造函数…用成员函数重载实现is_default_constructible
首先介绍一个C标准库提供的可变参类模板std::is_default_constructible。这个类模板的主要功能是判断一个类的对象是否能被默认构造所谓默认构造就是构造一个类对象时不需要给该类的构造函数传递任何参数。例如有一个类A和一个类B代码如下。
#include killCmake.h#includestring
using namespace std;class A {
};class B
{
public:B(int tmpval) {}
};int main()
{A a_obj;// E0291: 类 B 不存在默认构造函数B b_obj;// 要构造类B对象必须给类B的构造函数提供一个参数B b_obj(1);return 0;
}
现在可以使用std::is_default_constructible判断类A和类B对象是否能被默认构造该类没有构造函数或有一个不带参数的构造函数。在main()主函数中添加代码
#include killCmake.h#includestringusing namespace std;class A {
};class B
{
public:B(int tmpval) {}
};int main()
{std::cout std::is_default_constructibleint::value std::endl;std::cout std::is_default_constructibledouble::value std::endl;std::cout std::is_default_constructibleA::value std::endl;std::cout std::is_default_constructibleB::value std::endl;return 0;
} 从结果中可以看到int、double等基本类型内部类型对象以及类A对象都是可以默认构造的结果为1而类B对象因为其构造函数带一个形参该形参没有默认值所以无法默认构造。 在明白了std::is_default_constructible的功能后现在就来深入了解一下它的实现源码。 如果让你来实现一个与std::is_default_constructible同样的功能借此看一看如何使用SFINAE特性萃取一些重要信息这里要萃取的信息是判断某个类是否“没有构造函数或有一个不带参数的构造函数”满足这个条件的类就能够默认构造。IsDefConstructible类模板的代码如下。
templatetypename T
class IsDefConstructible
{
private:templatetypename decltype(T())static std::true_type test(void*);templatetypename intstatic std::false_type test(...);public:static constexpr bool value IsSameTypedecltype(test(nullptr)), std::true_type::value;
};
1有两个同名的静态成员函数模板test()。注意观察第1个test()的返回类型是std::true_type而第2个test()的返回类型是std::false_type。第1个test()的形参是void*而第2个test()的形参是3个点…这个形参读者应该不陌生是C语言中的省略号形参代表它可以接受0到任意多个实参。 尤其要注意第1个和第2个test()的模板参数都有默认值第1个test()的模板默认值比较关键decltype(T())要重点留意。两个test()都只有声明而没有实现体因为做类型推断一类事物一般涉及decltype的时候往往不需要具体的实现。2对于这两个test()静态成员函数重载函数调用的时候编译器会优先选择有具体形参的test()版本只有该test()版本不匹配时才会选择带省略号形参的test()版本带省略号的形参具有最低的匹配优先级。换句话说优先匹配第1个test()版本只有第1个test()版本不匹配时才会去匹配第2个test()版本。3最关键的是静态成员变量value的取值value的最终取值是一个布尔值true1或false0。如果value最终取值为1就表示通过模板参数传递给IsDefConstructible的类对象能默认构造如果value最终取值为0就表示通过模板参数传递给IsDefConstructible的类对象不能默认构造。看一看value的最终取值是经过怎样的计算得到的也就是重点分析下面这行代码
IsSameType decltype(test(nullptr)), std::true_type::value;上面这行代码用前面讲过的IsSameType…::value判断decltype(test(nullptr))和std::true_type这两个类型是否相等如果相等就返回true否则返回false。重点就是代码段decltype(test(nullptr))这段代码利用decltype判断test()函数的返回类型如果传递给IsDefConstructible的类型T支持默认构造那么显然编译器会选择第1个test()并通过decltype推导出返回类型为std::true_type从而使IsSameType…::value返回true如果传递给IsDefConstructible的类型T不支持默认构造那么第1个test()就不会成立因其类型模板参数的默认值不支持类型T的默认构造导致decltype(T())的写法根本就不成立根据SFINAE特性编译器会选择第2个test()然后通过decltype推导出返回类型为std::false_type从而使IsSameType…::value返回false。以上就是IsDefConstructible类模板的实现细节。现在可以对main()主函数的代码行进行修改测试IsDefConstructible类模板能否正常工作。