【enable_if】
SFINAE是英文Substitution failure is not an error的缩写. 这句话什么意思呢?当调用模板函数时编译器会根据传入参数推导最合适的模板函数,在这个推导过程中如果某一个或者某几个模板函数推导出来是编译无法通过的,只要有一个可以正确推导出来,那么那几个推导得到的可能产生编译错误的模板函数并不会引发编译错误。
struct Test { typedef int foo; }; template <typename T> void f(typename T::foo) {} // Definition #1 template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); // Call #1. f<int>(10); // Call #2. Without error (even though there is no int::foo) thanks to SFINAE. }
这是wiki上SFINAE的一个经典示例,注释已经解释的相当明白,由于推导模板函数过程中可以找到一个正确的版本,所以即时int::foo是一个语法错误,但是编译器也不会报错。这就是SFINAE要义。在C++11中,标准确立了这种编译的行为
enable_if 的实现:
看一下应用。
下在是更为常用的应用,用于区分函数的实现:
std::enable_if的运用使这两个函数的返回值在同一个函数调用的推导过程中只有一个合法,遵循SFINAE原则,则可以顺利通过编译。看一下调用:
参考:https://www.jianshu.com/p/a961c35910d2
【std::is_trivial】
If T
is TrivialType (that is, a scalar type, a trivially copyable class with a trivial default constructor, or array of such type/class, possibly cv-qualified), provides the member constant value
equal true. For any other type, value
is false.
数值类型::value 为true,否则 ::value为false
Helper variable template
参考:https://en.cppreference.com/w/cpp/types/is_trivial
【std::tie】
tie 有两个功能。
1、pack成一个 tuple,所以可以用于快速比较。如下:
struct S { int n; std::string s; float d; bool operator<(const S& rhs) const { // compares n to rhs.n, // then s to rhs.s, // then d to rhs.d return std::tie(n, s, d) < std::tie(rhs.n, rhs.s, rhs.d); } };
2、可以用于 unpack tuple、pair
int main() { std::set<S> set_of_s; // S is LessThanComparable S value{42, "Test", 3.14}; std::set<S>::iterator iter; bool inserted; // unpacks the return value of insert into iter and inserted std::tie(iter, inserted) = set_of_s.insert(value); if (inserted) std::cout << "Value was inserted successfully\n"; }
参考: