[英]Why does the compiler want a trailing return-type?
我在玩一個適配器,該適配器使用基於范圍的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'的左邊必須有class / struct / 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開始修復。謝謝,微軟公司的人。
OP中的注釋: VC ++有錯誤。 VC ++ 2015正確接受代碼。
我的原來的答案在於該VC ++否決在標准不允許的代碼實際上是錯誤的:它允許作為約翰內斯Schaub的指出:在5.1 [expr.prim.general]段落12中描述了其中一個id-表達式表示的非可以使用靜態數據成員或非靜態成員函數。 特別是最后一句指出:
如果該id表達式表示一個非靜態數據成員,並且出現在未評估的操作數中。
decltype(expr)
中的decltype(expr)
是未求值的操作數。 此外,9.3.1 [class.mfct.non靜電]段落3,說明了將情況this
是隱式加入的表達式:
當在類X的成員中使用不屬於類成員訪問語法(5.2.5)且不用於形成指向成員(5.3.1)的指針的id表達式(5.1)時,可以使用(5.1.1),如果名稱查找(3.4)將id-expression中的名稱解析為某些C類的非靜態非類型成員,並且id-expression可能被求值或者C為X或X的基類,使用(* this)(9.3.2)作為左側的后綴表達式,將id表達式轉換為類成員訪問表達式(5.2.5)。 操作員。
所討論的上下文不是“潛在評估”的,也不涉及任何依據。 因此, this
不會添加,也不必在范圍內。 放在一起,這意味着聲明
decltype(fwd.rbegin()) begin() const;
應該是合法的。 似乎使用
decltype(static_cast<Reverser<Fwd> const*>(0)->fwd.rbegin()) begin() const;
如果編譯器未正確實現,則可以使用此解決方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.