微软的文档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
是,则将实例化加倍过载,否则将选择平方过载。
当T
是int
,条件:
!std::is_same<T,int>::value
控制所述平方过载的SFINAE参数为假。因此 类型说明符:
typename std::enable_if<!std::is_same<T,int>::value, void **>::type = nullptr
无法编译。这是模板解析中的替代失败。将 int
替换为T
中的平方过载为不可行。所以平方过载从运行中消除了 ,并且只剩下加倍过载来实例化函数调用 。
当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
使用重载例如当(AB),它可以是有用的。 – BartoszKP 2015-03-13 19:08:56
无法到达'omull'部分。 – Jarod42 2015-03-13 19:22:04
enable_if启用该功能,而不是参数。 – 2015-03-13 19:39:23