我不太明白下面的代码,模板有两个参数,第二个有class = xxxx
,这对我来说似乎很奇怪。你能解释一下我该怎么理解它?除了std::enable_if
之外,这个c ++ 功能还有其他用例吗?
template < class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even (T i) {return !bool(i%2);}
答案 0 :(得分:3)
一个字:SFINAE。
替换失败不是错误。
通过谷歌寻找这个词,一个全新的世界将为你打开。
让我们看看代码的含义。
std::is_integral<typename T>::value
它是一个布尔值,取决于类型T
,如果true
是整数类型,则值为T
,否则为false
。
std::enable_if<bool B, typename T = void>::type
类型T
,B == true
时,否则为其他任何内容。
所以,在你的代码中
template < class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
当T
是一个整数类型时,第二个(未命名的)模板参数被替换为一个类型(默认值:void
;但是,在这种情况下,确切的类型是无关的)和功能被激活。相反,当T
不是整数类型时,替换第二个模板参数失败,并且未激活此is_even()
函数版本(对于类型{{1并且,这是重点,它不是错误(可以激活T
的另一个版本。)
更有趣的是,可以看到如何为非整数类型实现is_even()
的替代版本。您可以认为可以实现另一个否定is_even()
std::is_integral
但是这不起作用(是一个错误并且不编译),因为你有两个template < class T,
class = typename std::enable_if<false == std::is_integral<T>::value>::type>
模板化函数(仅从模板参数的角度来看)与默认参数不同。
解决方案可以将SFINAE应用于返回值
is_even()
通过这种方式,您可以为整数类型启用#include <type_traits>
#include <iostream>
template <typename T>
typename std::enable_if<true == std::is_integral<T>::value, bool>::type
is_even (T const & i)
{ return ! (i%2); }
template <typename T>
typename std::enable_if<false == std::is_integral<T>::value, bool>::type
is_even (T const &)
{ return false; }
int main()
{
std::cout << "-- is 7 even ? " << is_even(7) << '\n';
std::cout << "-- is 8UL even ? " << is_even(8LL) << '\n';
std::cout << "-- is \"abc\" even ? " << is_even("abc") << '\n';
return 0;
}
版本,为非整数类型启用第二个版本(甚至返回is_even()
)。
p.s:抱歉我的英语不好。