目录
使用了SFINAE特性的信息萃取
- SFINAE:替换失败并不是 一个错误
用成员函数重载实现is_default_constructible
【std::is_default_constructible】
- 判断一个类的对象是否能够被默认构造
class A {}; class B { public: B(int tmpval) {}; };
- 调用
cout << std::is_default_constructible<int>::value << endl; cout << std::is_default_constructible<double>::value << endl; cout << std::is_default_constructible<A>::value << endl; cout << std::is_default_constructible<B>::value << endl;
- 输出
【is_default_constructible功能实现方法1】
template <typename T> class IsDefConstructible { private: template <typename = decltype(T())> static std::true_type test(void*); //学习std::declval时看到过只声明,不实现的范例。 template <typename = int> // 根据SFINAE,上面不满足被忽略就执行这一行 static std::false_type test(...); //...是C语言中的省略号形参,代表可以接受0到多个实参。 //带省略号形参的test具有最低优先级 public: static constexpr bool value = std::is_same< decltype(test(nullptr)), std::true_type>::value; };
- 调用
cout << IsDefConstructible<int>::value << endl; cout << IsDefConstructible<double>::value << endl; cout << IsDefConstructible<A>::value << endl; cout << IsDefConstructible<B>::value << endl;
- 输出
【is_default_constructible功能实现方法2】
template <typename T> class IsDefConstructibleHelper { private: template <typename = decltype(T())> static std::true_type test(void*); template <typename = int> //这行代码其实可以不要 static std::false_type test(...); public: using type = decltype(test(nullptr)); }; template <typename T> class IsDefConstructible :public IsDefConstructibleHelper<T>::type { };
用成员函数重载实现is_convertible
【std::is_convertible】
- 判断能否从某个类型隐式的转换到另一个类型。
class A {}; class B :public A { };
- 调用
cout << std::is_convertible<float, int>::value << endl; //1 cout << std::is_convertible<int , float>::value << endl; //1 cout << std::is_convertible<A,B>::value << endl; //0 cout << std::is_convertible<B,A>::value << endl; //1
【std::is_convertible功能实现】
template <typename FROM,typename TO> struct IsConvertibleHelper { private: static void testfunc(TO); template<typename = decltype(testfunc(std::declval<FROM>()))> static std::true_type test(void*); static std::false_type test(...); public: using type = decltype(test(nullptr)); }; template <typename FROM,typename TO> struct IsConvertible : IsConvertibleHelper<FROM, TO>::type //struct默认的继承方式是public { }; //变量模板 template <typename FROM, typename TO> constexpr bool IsConvertible_v = IsConvertible<FROM, TO>::value;
- 调用
cout <<IsConvertible_v<float, int> << endl; cout <<IsConvertible_v<int, float> << endl; cout <<IsConvertible_v<A,B> << endl; cout <<IsConvertible_v<B,A> << endl;
- 输出