1

私が取り組んでいるいくつかのシリアライゼーションを大まかに表す次のコードは、g++ ( http://ideone.com/0rsGmt ) でコンパイルされますが、Visual Studio Express 2013 RC は次のエラーで失敗します。

Error 1 error C2326: 'void foo::print(void)' : function cannot access 'foo::bar::member_'
Error 2 error C2039: 'bar' : is not a member of 'foo'

コード:

#include <iostream>

class foo
{   
    private:
        struct bar
        {
            int member_;
        };

    public:
        void print()
        {
            std::cout << sizeof(decltype(foo::bar::member_)) << std::endl;
        }
};

int main(int argc, char* argv[])
{
    foo f;
    f.print();
    return 0;
}

どうしたの?Visual Studio の不備か何か?明らかに、構造体宣言をクラスの外に移動できます。Daniel Frey は以下の回避策を提供しています。しかし、上記のコードが Visual Studio でそのままコンパイルされない理由を知りたいです。

更新:受け入れられた回答では、機能するはずですが、Microsoft では一般的であるように機能しません。ここにバグ レポートを記入しました: http://connect.microsoft.com/VisualStudio/feedback/details/801829/incomplete-decltype-support-in-c-11-compiler

(誰かが質問のより良いタイトルを提案できるなら、私はそれを感謝します!)

4

2 に答える 2

2

によると、あなたのコードは(GCCまたはClangのように)動作するはずだと思います

5 式 [expr]

8一部のコンテキストでは、未評価のオペランドが表示されます (5.2.8、5.3.3、5.3.7、7.1.6.2)。未評価のオペランドは評価されません。評価されていないオペランドは完全な式と見なされます。[注:未評価のオペランドでは、非静的クラス メンバーに名前を付けることができ (5.1)、オブジェクトまたは関数の名前付け自体は、定義を提供する必要はありません (3.2)。—エンドノート]

VC++ はメモが明確にする内容を実装していないようです。そのため、VC++ を満足させるための回避策として (偽の) インスタンスが必要です。これはうまくいくはずです:

void print()
{
    std::cout << sizeof(std::declval<bar>().member_) << std::endl;
}

式を直接操作できるdecltypeasを削除したことに注意してください。sizeof

于 2013-09-21T06:45:28.390 に答える