Scott Meyers 发布了他的下一本书 EC++11 的内容和状态。他写道,书中的一项内容可能是 “Avoidstd::enable_ifin function signatures”。
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; } };
将 hack 放入模板参数 中。
模板参数方法比enable_if其他方法至少有两个优点:
enable_if
可读性 : enable_if 使用和返回/参数类型没有合并到一个杂乱的类型名称消歧器和嵌套类型访问块中;即使可以使用别名模板来减轻消歧器和嵌套类型的混乱,但这仍然会将两个不相关的东西合并在一起。enable_if 的使用与模板参数有关,与返回类型无关。将它们放在模板参数中意味着它们更接近重要的东西;
普遍适用性 :构造函数没有返回类型,并且一些运算符不能有额外的参数,因此其他两个选项都不能应用于任何地方。将 enable_if 放在模板参数中适用于任何地方,因为无论如何您只能在模板上使用 SFINAE。
对我来说,可读性方面是这个选择的最大动力。