gpt4 book ai didi

c++ - 为什么编译器需要尾随返回类型?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:30:41 24 4
gpt4 key购买 nike

我正在尝试使用基于范围的 for 循环反向迭代的适配器。 (我不知道用于该目的的升压适配器(“适配器”)。如果它是我已经下载的免费轮子,我坚信不会重新发明轮子。)

令我困惑的是为什么 VC++ 2012 不满意,除非我在下面的代码中使用尾随返回类型:

#include <string>
#include <iostream>

template<class Fwd>
struct Reverser {
const Fwd &fwd;
Reverser<Fwd>(const Fwd &fwd_): fwd(fwd_) {}
auto begin() -> decltype(fwd.rbegin()) const { return fwd.rbegin(); }
auto end() -> decltype(fwd.rend()) const { return fwd.rend(); }
};

template<class Fwd>
Reverser<Fwd> reverse(const Fwd &fwd) { return Reverser<Fwd>(fwd); }

int main() {
using namespace std;
const string str = ".dlrow olleH";
for(char c: reverse(str)) cout << c;
cout << endl;
}

当我尝试以下操作时,出现错误“错误 C2100:非法间接”和“错误 C2228:'.rbegin' 的左侧必须具有类/结构/union ”。我错过了什么?

template<class Fwd>
struct Reverser {
const Fwd &fwd;
Reverser<Fwd>(const Fwd &fwd_): fwd(fwd_) {}
decltype(fwd.rbegin()) begin() const { return fwd.rbegin(); }
decltype(fwd.rend()) end() const { return fwd.rend(); }
};

更新:根据关于“this”指针的讨论,我尝试了另一种方法。看,妈妈,没有这个!它编译得很好。我确实相信,无论对错,VC++ 都没有意识到这一点。

template<class Fwd>
struct Reverser {
const Fwd &fwd;
Reverser<Fwd>(const Fwd &fwd_): fwd(fwd_) {}
decltype(((const Fwd*)0)->rbegin()) begin() const { return fwd.rbegin(); }
decltype(((const Fwd*)0)->rend()) end() const { return fwd.rend(); }

};

更新 2:提交给 MS:https://connect.microsoft.com/VisualStudio/feedback/details/765455/vc-2012-compiler-refuses-decltype-return-spec-for-member-function

更新 3:自 VC++ 2015 起,此问题已得到解决。谢谢,Microsoft 人员。

最佳答案

OP 的注释:VC++ 有问题。 VC++ 2015 正确接受代码。

我最初的回答是 VC++ 拒绝的代码在标准中是不允许的实际上是错误的:正如 Johannes Schaub 指出的那样,它是允许的:在 5.1 [expr.prim.general] 第 12 段中描述了 id可以使用表示非静态数据成员或非静态成员函数的表达式。特别是,最后一个项目符号指出:

if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

decltype(expr) 中的表达式是未计算的操作数。此外,9.3.1 [class.mfct.non-static] 第 3 段解释了将 this 隐式添加到表达式的情况:

When an id-expression (5.1) that is not part of a class member access syntax (5.2.5) and not used to form a pointer to member (5.3.1) is used in a member of class X in a context where this can be used (5.1.1), if name lookup (3.4) resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression (5.2.5) using (*this) (9.3.2) as the postfix-expression to the left of the . operator.

所讨论的上下文不是“可能评估的”,也没有涉及任何基础。因此,this 没有被添加并且不必在范围内。综合起来,这意味着声明

decltype(fwd.rbegin()) begin() const;

应该是合法的。好像是用

decltype(static_cast<Reverser<Fwd> const*>(0)->fwd.rbegin()) begin() const;

在编译器未正确实现的情况下是一种变通方法。

关于c++ - 为什么编译器需要尾随返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12656548/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com