【问题标题】:template identifier vs decltype in template function parameter type模板函数参数类型中的模板标识符与 decltype
【发布时间】:2017-06-20 11:30:13
【问题描述】:

你认为什么更好?

template <typename T> void func(T x,T y) {}

template <typename T> void func(T x,decltype(x) y) {}

恕我直言,第二种形式似乎更可取,因为 x 和 y 类型之间的链接是明确的,并且至少在重命名模板标识符时似乎不太容易出错。

编辑

第二种形式允许您使用第一个参数的子类型调用函数,而第一种形式需要完全相同的类型。这个论点似乎比前一个要好一些。

【问题讨论】:

  • 第二种形式似乎也没有必要被混淆。
  • 我并没有真正了解decltype 替代方案的用例。想详细说明你为什么想要这样的东西?
  • 第二种形式不会为y 启用隐式转换,而第一种不会?
  • @Jean-BaptisteYunès decltype 的操作数确实是 non-deduced context
  • @Jean-BaptisteYunès,也许您希望它是对称的,这取决于您的应用程序。我认为 decltype 版本类似于template&lt;typename T&gt; void func(T x, typename identity&lt;T&gt;::type y){}。所以,这不是什么更正确或更明确的问题,而是你想要实现什么的问题。这两个选项在语义上是不同的,尽管在许多情况下它们的行为相似。

标签: c++ c++11 templates decltype


【解决方案1】:

它们在语义上是不同的,所以这取决于你想要实现什么。第二个比第一个更严格。考虑:

template <typename T> void func1(T x, decltype(x) y) {}
template <typename T> void func2(T x, T y) {}

func1(2., 4); // converts 4 to double
func2(2., 4); // fails to compile

在 SFINAE 上下文中,它可能导致不同的编译时行为(不一定是编译错误),并且这两个选项可以间接编译到不同的程序。

【讨论】:

    【解决方案2】:

    这两种形式并不意味着完全相同。第二个是非演绎的。

    第一个也不允许对其中一个参数进行隐式转换(不仅是子类型),因为这样它就无法将预期的类型(比如int)与要转换的类型统一起来(让我们说float):See on coliru

    【讨论】:

      猜你喜欢
      • 2018-10-23
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多