Scott Meyers发布了他的下一本书EC++11的内容和状态。他写道,书中的一项可能是“避免在函数签名中使用std::enable_if
”。
std::enable_if
可以用作函数参数、返回类型或类模板或函数模板参数,以有条件地从重载解析中删除函数或类。
这个问题中展示了所有三种解决方案。
作为函数参数:
template<typename T>
struct Check1
{
template<typename U = T>
U read(typename std::enable_if<
std::is_same<U, int>::value >::type* = 0) { return 42; }
template<typename U = T>
U read(typename std::enable_if<
std::is_same<U, double>::value >::type* = 0) { return 3.14; }
};
作为模板参数:
template<typename T>
struct Check2
{
template<typename U = T, typename std::enable_if<
std::is_same<U, int>::value, int>::type = 0>
U read() { return 42; }
template<typename U = T, typename std::enable_if<
std::is_same<U, double>::value, int>::type = 0>
U read() { return 3.14; }
};
作为返回类型:
template<typename T>
struct Check3
{
template<typename U = T>
typename std::enable_if<std::is_same<U, int>::value, U>::type read() {
return 42;
}
template<typename U = T>
typename std::enable_if<std::is_same<U, double>::value, U>::type read() {
return 3.14;
}
};
- 哪种解决方案应该优先选择,为什么要避免其他方案?
- 在哪些情况下,"避免在函数签名中使用
std::enable_if
" 涉及作为返回类型的用法(这不是普通函数签名的一部分,而是模板特化的一部分)? - 成员函数和非成员函数模板有什么区别?
std::enable_if
在我的函数签名中弄乱(特别是丑陋的额外nullptr
函数参数版本),因为它总是看起来像它是一个奇怪的黑客(对于一些可能更美丽和干净的东西,如static if
,使用模板黑魔法来利用一个有趣的语言特性)。这就是为什么我尽可能使用标签分派(好吧,你仍然有额外的奇怪参数,但不在公共接口中,而且也少得多丑陋和神秘)。 - Christian Rautypename std::enable_if<std::is_same<U, int>::value, int>::type = 0
中的=0
是什么意思?我找不到正确的资源来理解它。我知道在=0
之前的第一部分,如果U
和int
相同,则具有成员类型int
。非常感谢! - astroboylrx