簡體   English   中英

為什么編譯器需要尾隨返回類型?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM