问题描述
Scott Meyers 发布了内容和状态他的下一本书 EC++11.他写道,书中的一项可能是避免在函数签名中使用std::enable_if
".
Scott Meyers posted content and status of his next book EC++11.
He wrote that one item in the book could be "Avoid std::enable_if
in function signatures".
std::enable_if
可用作函数参数、返回类型或类模板或函数模板参数,以有条件地从重载解析中删除函数或类.
std::enable_if
can be used as a function argument, as a return type or as a class template or function template parameter to conditionally remove functions or classes from overload resolution.
在这个问题中显示了所有三个解决方案.
In this question all three solution are shown.
作为函数参数:
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
" 涉及作为返回类型的使用(它不是普通函数签名的一部分,而是模板特化的一部分)? - 成员函数模板和非成员函数模板有什么区别吗?
可读性:enable_if 的使用和返回/参数类型没有合并成一大块类型名称消歧器和嵌套类型访问;尽管可以使用别名模板减轻消歧器和嵌套类型的混乱,但这仍然会将两个不相关的东西合并在一起.enable_if 的使用与模板参数有关,而不是与返回类型有关.将它们包含在模板参数中意味着它们更接近重要的内容;
readability: the enable_if use and the return/argument types are not merged together into one messy chunk of typename disambiguators and nested type accesses; even though the clutter of the disambiguator and nested type can be mitigated with alias templates, that would still merge two unrelated things together. The enable_if use is related to the template parameters not to the return types. Having them in the template parameters means they are closer to what matters;
推荐答案
将 hack 放入模板参数.
模板参数方法的 enable_if
至少有两个优点:
The enable_if
on template parameter approach has at least two advantages over the others:
普遍适用:构造函数没有返回类型,有些运算符不能有额外的参数,所以其他两个选项都不能在任何地方应用.将 enable_if 放在模板参数中适用于任何地方,因为无论如何您只能在模板上使用 SFINAE.
universal applicability: constructors don't have return types, and some operators cannot have extra arguments, so neither of the other two options can be applied everywhere. Putting enable_if in a template parameter works everywhere since you can only use SFINAE on templates anyway.
对我来说,可读性是这个选择的重要推动因素.
For me, the readability aspect is the big motivating factor in this choice.
这篇关于为什么我应该在函数签名中避免 std::enable_if的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!