函数标题中的箭头运算符( - >)

use*_*567 111 c++ decltype auto c++11

我找到了这样的代码:

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

我想到了所有细节,这对我来说是新的,但只有一个.请告诉我,在哪里可以阅读,箭头操作符(->)在函数标题中的含义是什么?我纯粹从逻辑上说,那个->算子确定了一个类型,auto但是我希望得到这个,但找不到信息.

Jan*_*dec 177

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

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

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

它们是等价的.现在当它们相同时,你为什么要使用后者呢?好吧,C++ 11引入了这个很酷的decltype东西,可以让你描述一个表达式的类型.因此,您可能希望从参数类型派生返回类型.所以你试试:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);
Run Code Online (Sandbox Code Playgroud)

并且编译器会告诉你它不知道参数中的内容a和内容.那是因为它们只是由参数列表声明.bdecltype

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

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);
Run Code Online (Sandbox Code Playgroud)

除了它现在变得非常冗长.因此,提出并实现了备用声明语法,现在您可以编写

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);
Run Code Online (Sandbox Code Playgroud)

并且它不那么冗长,并且范围规则不需要改变.


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

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

只要函数在使用前完全定义,并且所有return语句都推导为相同类型.的->,如果你要隐藏的身体在源文件中的语法仍然是公共职能(在头部声明)是有用的.显然有些模板无法完成,但有一些具体的类型(通常是通过模板元编程推导出来的),否则难以编写.

  • 非常好,整洁且内容丰富的回复@Jan Hudec。表示赞许,满意,胜利。`C++14` 中有什么改变,因为我在这样的函数中使用 `auto` 作为 `return` 类型,而不需要 `-&gt; decltype(a + b)` 部分。它现在是多余的还是在其他情况下仍然应该使用它?还是编译器特定的扩展? (5认同)
  • @Kostas,我确实是认真写的。对于私有函数,您通常可以确保它在使用之前已定义,因此您可以仅使用“auto”(来自 C++14)。它是*公共*函数,通常在未*定义*(仅声明)的地方使用,因此它仍然需要使用 `-&gt;` 符号。当然,如果您可以命名返回类型,您就可以这样做,但是整个讨论是关于您想要推断它的情况,当您*不能*(轻松)*命名类型时,就会发生这种情况。* (2认同)

mur*_*att 19

用简单的英语告诉它返回类型是和的a和的推断类型b.


Cha*_*alk 5

除了decltypedeclval的使用之外,您还可以使用类中定义的返回类型来定义类成员函数,而无需Class::再次提供范围解析前缀。

例子:

class SomeLongClassname
{
public:
  typedef std::shared_ptr<Node> PNode;

  PNode make_node ();
};
Run Code Online (Sandbox Code Playgroud)

选择:

SomeLongClassname::PNode SomeLongClassname::make_node () { ... }
Run Code Online (Sandbox Code Playgroud)

或者

auto SomeLongClassname::make_node () -> PNode { ... }
Run Code Online (Sandbox Code Playgroud)

第二种形式有时更清晰。