c++学习笔记(11)-SFINAE

1、概念

SFINAE 是 Substitution Failure Is Not An Error 的缩写,表示“替换失败不是一个错误”。指的是,当编译器遇到模板参数不符合要求的情况时,会跳过这个无法匹配的模板,继续寻找合适的模板。举个例子:

struct Test {
  typedef int foo;
};

template <typename T>
void f(typename T::foo) {std::cout<<"定义一"<<std::endl;}

template <typename T>
void f(T) {std::cout<<"定义二"<<std::endl;}

int main() {
  f<Test>(10);  // 输出:定义一.
  f<int>(10);   // 输出:定义二
  return 0;
}

2、应用

SFINAE一般用于函数重载和编译期间类型检查,标准库中很多type traits模板就是通过SFINAE实现的。下面举个例子,该模板用于检查某个类内是否有特定类型的成员:

#include 

template <typename T>
struct has_typedef_foobar {
  typedef char yes[1];
  typedef char no[2];

  template <typename C>
  static yes& test(typename C::foobar*);

  template <typename>
  static no& test(...);

  static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};

struct foo {
  typedef float foobar;
};

int main() {
  std::cout << std::boolalpha;
  std::cout << has_typedef_foobar<int>::value << std::endl;  //false
  std::cout << has_typedef_foobar<foo>::value << std::endl;  //true
  return 0;
}

编译期间,会对静态成员变量value进行初始化——执行代码value = sizeof(test(nullptr)) == sizeof(yes);,由于int类型内部没有float类型,因此调用no& test(),返回类型为no,其大小为2,不等于sizeof(yes),故value为false;而foo类型内部有float类型,因此调用yes& test(),返回类型为yes,其大小为1,等于sizeof(yes),故value为true。

3、参考

https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error

你可能感兴趣的:(C++笔记,c++,学习,笔记)