这是代码:
#include <iostream>
#include <type_traits>
template <class T>
typename std::enable_if<std::is_integral<T>::value,bool>::type
is_odd (T i) {return bool(i%2);}
// 2. the second template argument is only valid if T is an integral type:
template < class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even (T i) {return !bool(i%2);}
int main() {
short int i = 1; // code does not compile if type of i is not integral
std::cout << std::boolalpha;
std::cout << "i is odd: " << is_odd(i) << std::endl;
std::cout << "i is even: " << is_even(i) << std::endl;
return 0;
}
我正在努力学习 enable_if
的正确用法,我知道如果它被用作返回类型说明符是:编译器将忽略该代码。意思是,该函数不会在二进制文件中。
如果在模板参数中使用它,我会感到有些困惑。根据上面的代码,它说第二个模板参数只有在 T 是整数类型时才有效
但是我很困惑第二个参数的目的是什么?
我将其删除并将其更改为:
template < class T>
bool is_even (T i) {return !bool(i%2);}
它仍然可以正常工作。有人可以澄清一下它的真正目的是什么吗?它也没有变量说明符。
或者如果我做了类似的事情,它可能只是作为检查器使用
template < class T,
class B= typename std::enable_if<std::is_integral<T>::value>::type>
允许我在我的代码上访问 B(可以是 true 或 false)?
最佳答案
您正在将它与整数类型一起使用。它只会在与非整数类型一起使用时失败。以下应该无法编译:
float f;
is_even(f);
请注意,使用 C++14 编译器,您可以 can write :
template <class T,
class = std::enable_if_t<std::is_integral<T>::value>>
但是,您可能想要使用 static_assert在这里,因为该函数可能对非整数类型没有意义,它会在编译时给出更好的错误消息。
SFINAE 中附加参数的另一种用法是降低对给定函数的偏好。与模板参数较少的模板相比,模板参数较多的模板被选中的可能性较小。
关于c++ - 没有变量说明符的模板参数上的 SFINAE(enable_if),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31126605/