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

Arrow operator (->) in function heading

本文关键字:gt 运算符 标题 函数      更新时间:2023-10-16

我遇到了以下代码:

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

有一件事我无法理解:

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

我想纯粹从逻辑上讲,->运算符确定一种类型,auto将被推导出来,但我想直截了当。我找不到任何信息。

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

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

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

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

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

编译器会告诉你,它不知道decltype参数中的ab是什么。那是因为它们仅由参数列表声明。

通过使用已声明的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语句都推导为同一类型。如果要在源文件中隐藏正文,则->语法对于公共函数(在标头中声明(仍然有用。很明显,这不能用模板来完成,但是有一些具体的类型(通常通过模板元编程派生(很难以其他方式编写。

用简单的英语来说,它告诉返回类型是 ab 之和的推断类型。

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

例:

class SomeLongClassname
{
public:
  typedef std::shared_ptr<Node> PNode;
  PNode make_node ();
};

选择:

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

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

第二种形式有时更清晰。