为什么要出现std::enable_if。我们已经可以搭建出匹配空间,但是当我们要实现条件编译的时候。就需要一个工具了,你可以把它当作基于SIFNAE的模板专用的if条件语句.std库提供的就是std::enable_if。它的代码其实很简单。
源代码
template<bool B, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> {
typedef T type;
};
赏析
但是毕竟是写在STD里的。下面我们来简单赏析一下
- 为什么要写两个参数?感觉一个参数也行?
- 为了方便的给模板函数提供返回值(enable_if常用于函数返回值上的匹配)
示例
-
using namespace std; #include <iostream> #include <type_traits> // For std::enable_if // 函数模板,仅当T是整数类型时才可用 template<typename T> typename std::enable_if<std::is_integral<T>::value, void>::type print(T value) { std::cout << "int: " << value << std::endl; } // 函数模板,仅当T不是整数类型时才可用 template<typename T> typename std::enable_if<!std::is_integral<T>::value, void>::type print(T value) { std::cout << "not int: " << value << std::endl; } int main() { print(42); // 调用整型版本 print(3.14); // 调用非整型版本 return 0; }
解析
-
print(42);
-
编译器先尝试匹配第一个模板
typename std::enable_if< std::is_integral< T >::value, void>::type print(T value)
T=decltype(42),std::is_integral< T >::value=true,enable_if模板使用template<class T> struct enable_if<true, T> { typedef T type; };
这个模板,有类型成员type,对上了typename std::enable_if<std::is_integral< T>::value, void>::type 匹配成功
-
-
print(3.14);
-
编译器先尝试匹配第一个模板
typename std::enable_if< std::is_integral< T >::value, void>::type print(T value)
T=decltype(3.14),std::is_integral< T >::value=false,enable_if模板使用,使用template<bool B, class T = void> struct enable_if {};
这个模板,但是这个模板里没有type成员,所以模板函数
typename std::enable_if<std::is_integral< T>::value, void>::type print(T value)
的返回值匹配失败,不使用这个模板,使用第二个模板,剩余的推导过程和上面同理
-