微软的文档there
那里清澈如泥。请改用this。
提供一个带有未命名默认参数的函数模板:
typename enable_if<your_condition, void **>::type = nullptr
(正如 MS 抄写员所建议的那样),在您希望的情况下(并且仅在情况下)很有用
编写具有不同行为的函数模板的多个重载
由一个或多个模板参数控制。然后,由
用表达适当的条件替换your_condition
对模板参数的要求,您可以使用SFINAE
选择要为其实例化的特定重载的原则
给定模板参数。
SFINAE 参数 - 我们称之为 - 是
实例化函数未使用;它的存在只是为了在函数模板中引发 SFINAE
重载决议。因此它可以是无名的,因此它必须是默认的:
它不能强迫你提供额外的、无用的论据
调用函数模板。
例如:
#include <type_traits>
#include <iostream>
template <typename T>
T foo(T && t,
typename std::enable_if<std::is_same<T,int>::value, void **>::type = nullptr)
{
std::cout << "Doubling " << t << " gives " << (t + t) << std::endl;
return t + t;
}
template <typename T>
T foo(T && t,
typename std::enable_if<!std::is_same<T,int>::value, void **>::type = nullptr)
{
std::cout << "Squaring " << t << " gives " << (t * t) << std::endl;
return t * t;
}
using namespace std;
int main()
{
cout << foo(2) << endl;
cout << foo(3.3) << endl;
return 0;
}
输出是:
Doubling 2 gives 4
4
Squaring 3.3 gives 10.89
10.89
在函数模板foo的这两个重载中,第一个加倍它是
输入 T 参数,第二个参数平方,一个 SFINAE
参数用于确定将实例化加倍重载
如果T 是int,否则将选择平方重载。
当T为int时,条件:
!std::is_same<T,int>::value
控制平方重载的 SFINAE 参数为假。所以
类型说明符:
typename std::enable_if<!std::is_same<T,int>::value, void **>::type = nullptr
编译失败。这是模板解析中的替换失败。替代
平方重载中的T 的int 不可行。所以平方过载是
从运行中消除,只剩下加倍重载来实例化
函数调用。
当T 是(比如说)double 而不是int 时,情况正好相反
并且只有平方重载才能在模板解析中幸存下来。致电foo(2)
你会加倍。打电话给foo(3.3),你就会得到平方数。
这里的 MS 样本 SFINAE 参数是不必要的冗长。
template< bool B, class T = void >
struct enable_if;
根据 C++11 标准及更高版本,默认 T 为 void。像这样的:
typename std::enable_if<some_condition, void **>::type = nullptr
也可以简写为:
typename std::enable_if<some_condition>::type * = nullptr
从 C++14 开始,该标准具有:
template< bool B, class T = void >
using enable_if_t = typename enable_if<B,T>::type
所以同样的SFINAE参数可以进一步缩短为:
std::enable_if_t<some_condition> * = nullptr
将 SFINAE 函数模板参数应用于您在
帖子,你会写这样的:
enum ops {
add,
multiply
};
template<ops Op>
int op(int const & lhs, int const & rhs,
std::enable_if_t<Op == add> * = nullptr)
{
return lhs + rhs;
}
template<ops Op>
int op(int const & lhs, int const & rhs,
std::enable_if_t<Op == multiply> * = nullptr)
{
return lhs * rhs;
}
...
auto i = op<add>(2,3);
auto j = op<multiply>(2,3);
...
// C++14