我正在使用适配器来使用基于范围的for循环来反向迭代。 (为此目的,我不知道增强适配器(&#34;适配器&#34;)。如果它是我已下载的自由轮,我非常相信不重新发明轮子。)< / p>
令我感到困惑的是,除非我在后面的代码中使用尾随返回类型,否则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;
}
当我尝试以下操作时,我收到错误,&#34;错误C2100:非法间接,&#34;和&#34;错误C2228:左边的&#39; .rbegin&#39;必须有class / struct / union&#34;。我错过了什么?
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(); }
};
更新:根据关于&#34;这个&#34;的讨论。指针,我试了另一个大头钉。看马云,不,这个!它编译得很好。我确实相信,无论是对还是错,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(); }
};
更新3:从VC ++ 2015开始修复此问题。谢谢,微软的人。
答案 0 :(得分:5)
从OP注意: VC ++是错误的。 VC ++ 2015正确接受代码。
我原来的回答是VC ++拒绝的代码在标准中被禁止实际上是错误的:正如Johannes Schaub指出的那样:在5.1 [expr.prim.general]第12段中描述了 id可以使用表示非静态数据成员的表达式或非静态成员函数。特别是,最后一个子弹说明:
如果该id-expression表示非静态数据成员,并且它出现在未评估的操作数中。
decltype(expr)
中的表达式是未评估的操作数。此外,9.3.1 [class.mfct.non-static]第3段解释了this
被隐式添加到表达式的情况:
当一个id-expression(5.1)不属于类成员访问语法(5.2.5)并且不用于形成指向成员(5.3.1)的指针时,在类X的成员中使用可以使用的上下文(5.1.1),如果名称查找(3.4)将id-expression中的名称解析为某个类C的非静态非类型成员,并且如果id-expression可能被评估或者C是X或X的基类,使用(* this)(9.3.2)将id-expression转换为类成员访问表达式(5.2.5)作为后缀表达式 左边的。操作
有问题的背景不是“潜在评估”,并且没有涉及的基础。因此,this
未添加,不必在范围内。总之,这意味着声明
decltype(fwd.rbegin()) begin() const;
应该是合法的。似乎在使用
decltype(static_cast<Reverser<Fwd> const*>(0)->fwd.rbegin()) begin() const;
是在未正确实现编译器的情况下解决的问题。