为什么我应该在函数签名中避免 std::enable_if

时间:2023-02-23
本文介绍了为什么我应该在函数签名中避免 std::enable_if的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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" 涉及作为返回类型的使用(它不是普通函数签名的一部分,而是模板特化的一部分)?
  • 成员函数模板和非成员函数模板有什么区别吗?
  • 推荐答案

    将 hack 放入模板参数.

    模板参数方法的 enable_if 至少有两个优点:

    The enable_if on template parameter approach has at least two advantages over the others:

    • 可读性: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;

    普遍适用:构造函数没有返回类型,有些运算符不能有额外的参数,所以其他两个选项都不能在任何地方应用.将 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:为使用数组、向量、结构等传递给可变参数函数或可变参数模板函数的所有参数指定一种类型? 下一篇:CRTP 避免动态多态

相关文章

最新文章