函数标题中的箭头操作符(->

我遇到了以下代码:

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

有一件事我不能理解

我可以在哪里找到箭头操作符(->)在函数标题中的含义?

我猜纯粹是逻辑上的,->操作符决定了一个类型,auto将被推导出来,但我想弄清楚这一点。我找不到任何信息。

66092 次浏览

简单地说,它告诉返回类型是ab的和的推断类型。

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

,,, 返回类型 标识符 ( argument-declarations…… )

而且

,,, auto 标识符 ( argument-declarations…… ) -> return_type

它们是等价的。当它们相等时,为什么还要用后者呢?c++ 11引入了这个很酷的decltype东西,它允许你描述表达式的类型。你可能想从参数类型中派生返回类型。所以你试着:

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

编译器会告诉你它不知道abdecltype参数中是什么。这是因为它们只由参数列表声明。

你可以通过使用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 标识符 ( argument-declarations…… )

只要函数在使用前完全定义,并且所有return语句推导为相同的类型。如果你想在源文件中隐藏函数体,->语法对于公共函数(在头文件中声明)仍然很有用。显然,这不能用模板来完成,但是有一些具体的类型(通常通过模板元编程派生)很难用其他方法来编写。

除了decltypedeclval用法外,还可以使用类中定义的返回类型定义类成员函数,而不需要第二次提供Class::作用域解析前缀。

例子:

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


PNode make_node ();
};

选择:

SomeLongClassname::PNode SomeLongClassname::make_node () { ... }

auto SomeLongClassname::make_node () -> PNode { ... }

第二种形式有时更容易辨认。