Type Traits

type-traits是一种在编译时确定模板参数类型,或者对类型进行某些修改从而得到另一个相关类型的技巧。

标准库的type traits包括这些:https://en.cppreference.com/w/cpp/header/type_traits

type traits的实现常常是基于SFINAE技巧的。

SFINAE

Substitution Failure Is Not An Error。
替换失败不是错误。
指的是,在编译时,模板参数替换失败并不是错误,只要最终能够找到合法的替换即可。

C++专门定义了一组SFINAE规则,并非每一种模板中的错误构造都是SFINAE,只要spec中规定的SFINAE构造才会被视作SFINAE,编译器才会在能够找到合法替换时不报错,没有在SFINAE中规定的编译时错误,依然会在编译时报错。
https://en.cppreference.com/w/cpp/language/sfinae

看看下面这个例子:

  1. template<typename T>
  2. class is_class
  3. {
  4. typedef char yes[1];
  5. typedef char no[2];
  6. template<typename C>
  7. static yes& test(int C::*); // selected if C is a class type
  8. template<typename C>
  9. static no& test(...); // selected otherwise
  10. public:
  11. static bool const value = sizeof(test<T>(0)) == sizeof(yes);
  12. };

SFINAE代码并不那么好写,其构造比较奇特,边界条件不好检查,如果没有深思熟虑容易写出存在问题的代码,因此有用的SFINAE技巧几乎都已经收录进标准库中,我们应该避免自己写SFINAE代码。