为什么在 C++11 中需要添加尾随返回类型? [重复]

问题描述 投票:0回答:2

我终于开始阅读 ,但我无法理解为什么需要尾随返回类型。

我遇到了以下示例,它用于突出问题:

template<class Lhs, class Rhs>
  decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} 

该示例是非法的,因为

decltype(lhs+rhs)
不起作用,因为标识符
lhs
rhs
仅在解析阶段之后才有效。

我想我的问题是关于

decltype
类型决议的时间安排。如果我没记错的话,关键字
decltype
用于在编译时确定表达式的类型。

我没有看到让

decltype
在所有解析完成后执行类型解析的缺点(这对于上面的示例来说效果很好)。我相信这将是解决问题的更简单的方法......

相反,C++11 标准提供了尾随返回类型:

template<class Lhs, class Rhs>
  auto adding_func(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}

我毫不怀疑我错过了一些东西,因为我没有看到尾随返回类型的其他用法。我的推理哪里有缺陷?

尾随返回类型对我来说似乎是一个过于复杂的解决方案,因为在解析完整函数体后进行

decltype
类型解析也可以正常工作?

c++ c++11 compilation trailing-return-type
2个回答
18
投票

我没有看到在所有解析完成后让 decltype 执行类型解析的缺点(这对于上面的示例来说效果很好)。

缺点是,如果不从根本上改变 C++ 解析和处理模型的基本基础,这是不可能的。

为了执行您的建议,编译器必须查看

decltype
语法并对语法内容进行一些基本的词法分析。然后,它继续解析更多源文件。在稍后的某个时刻(什么时候?),它决定去,“嘿,我之前看过的那些东西?我现在要为它们做所有的解析工作。”

作为一般规则,C++ 不支持向前查找符号的定义。 C++解析框架的基本假设是,如果符号在使用之前没有声明,则会出现编译错误。 类可以不受前瞻的影响,但仅限于其成员。这部分是因为 id 表达式何时可以引用成员变量(即:如果它没有引用作用域中已声明的本地或全局变量),这一点非常清楚。这里的情况并非如此,我们不确定 id 表达式到底指的是什么。

此外,您的建议会产生歧义。这意味着什么:

int lhs; template<class Lhs, class Rhs> decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs &rhs);

decltype 语法是指全局 
lhs

变量,还是局部

lhs
函数参数?

我们现在的做法,两者之间有明确的界限:

int lhs; float rhs; template<class Lhs, class Rhs> decltype(lhs+rhs) adding_func1(const Lhs &lhs, const Rhs &rhs); template<class Lhs, class Rhs> auto adding_func2(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs);

adding_func1

指的是全局变量。

adding_func2
指的是函数参数。

因此,你可以从根本上破坏地球上所有的 C++ 编译器。或者您可以简单地稍后指定您的返回类型。

或者您可以采用 C++14 方法并且

根本不用费心去说明它


4
投票

typedef decltype(lhs+lhs) foo; foo lhs;

© www.soinside.com 2019 - 2024. All rights reserved.