功能标题中的箭头运算符(->)


128

我遇到以下代码:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

我无法理解的一件事是:

在哪里可以找到箭头->标题()在函数标题中的含义?我完全从逻辑上猜测,->运算符确定auto要推导的类型,但是我想弄清楚这一点。我找不到任何信息。


2
它是尾随返回类型语法的一部分。参见stackoverflow.com/a/4113390/962089
2014年

2
它不是运算符,而是语法的一部分。
texasbruce 2014年

1
在回答“我在哪里可以读?”时,C ++ Spec最权威。缺乏资金或不想花费$$,最后的工作草案通常足够接近且无成本。这些规范具有很高的技术术语,因此对阅读ISO规范不熟悉,请尝试cplusplus.com或cppreference.com或其他没有权威但通常非常准确的此类站点。注意:从C ++ 14开始,可以省略尾随返回类型。
莱斯

Answers:


205

在C ++ 11中,有两种用于函数声明的语法:

    返回类型 标识符 ( 参数声明... )

    auto 标识符 ( 参数声明... ) -> return_type

它们是等效的。现在,当它们相等时,您为什么要使用后者?好吧,C ++ 11引入了这一很酷decltype的功能,可让您描述表达式的类型。因此,您可能想从参数类型派生返回类型。因此,您尝试:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);

编译器会告诉你,这不知道是什么a,并b都在decltype争论。这是因为它们仅由参数列表声明。

您可以使用declval和已经声明的模板参数轻松解决此问题。喜欢:

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);

除了现在变得非常冗长。因此,提出并实现了替代声明语法,现在您可以编写

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);

而且它不太冗长,作用域规则也不需要更改。


C ++ 14更新: C ++ 14还允许

    auto 标识符 ( 参数声明... )

只要函数在使用前已完全定义并且所有return语句都推导为相同类型即可。的->,如果你要隐藏的身体在源文件中的语法仍然是公共职能(在头部声明)是有用的。显然,模板无法完成某些工作,但是有些具体类型(通常是通过模板元编程派生的)很难用其他方式编写。


2
很好,干净整洁且内容丰富的回复@Jan Hudec。表示赞许,满意,胜利。有什么在改变C++14,因为我使用autoreturn在这样的函数类型,而不需要的-> decltype(a + b)部分。现在是多余的还是在其他情况下仍应使用它?还是编译器特定的扩展?
Shadi

1
@ Shadi,C ++ 14包含N3638,它允许推导声明为的返回类型auto,而无需使用->符号,只要函数在使用前已完全定义且所有return语句均推导为同一类型即可。->如果要在将正文隐藏在源文件中的同时对公共功能使用演绎,则该表示法仍然有用。
Jan Hudec

23

用通俗的英语讲,它的返回类型是aand的和的推断类型b

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.