7

次のコードを検討してください。

#include <cstddef>

class A
{
public:
    struct B
    {
        int M;
    };

    static void StaticFunc();
};

void A::StaticFunc()
{
    const std::size_t s0 = sizeof(::A::B::M);
    const std::size_t s1 = sizeof(A::B::M);
    const std::size_t s2 = sizeof(B::M);
}

int main()
{
    const std::size_t s3 = sizeof(A::B::M);
    return 0;
}

GCC はそれをコンパイルし、未使用の変数について警告するだけです。

ただし、Visual C++ 2015 は次のようにコンパイルできません。

error C2326: 'void A::StaticFunc(void)': function cannot access 'A::B::M'

ライン上

const std::size_t s0 = sizeof(::A::B::M);
const std::size_t s1 = sizeof(A::B::M);

StaticFunc()

他の行s2 = ...、およびコンパイルs3 = ...で問題ありません。main()

これは MSVC のバグですか、それともここで何か基本的なことを見逃していますか?

4

1 に答える 1

5

これは MSVC のバグです。

C++11/14 では、評価されていないコンテキストで非静的クラス メンバーを使用できます。5.1.1 [expr.prim.general] p. 13:

クラスの非静的データ メンバーまたは非静的メンバー関数を示す id-expression のみを使用できます。

...

(13.3) — その id-expression が非静的データ メンバーを表し、それが未評価のオペランドに現れる場合。

[ 例:

    struct S {
       int m;
    };
    int i = sizeof(S::m);        // OK
    int j = sizeof(S::m + 42);   // OK

— 最後の例]

編集: MSVC はB::Mを受け入れ、受け入れないように見えますA::B::Mが、これはまったく説明のつかない動作です。それがバグ以外の何かである可能性があるかどうかはわかりません。

C++11 および C++14 モードの g++ のような clang++ は、プログラムを受け入れます。C++03 モードの clang++ は 4 つの参照をすべて拒否しますがM(C++03 には p. 13.3 のようなものはありません)、C++03 モードの g++ は引き続きそれらを受け入れます (これはおそらく g++ C++03 モードです)。バグ)。

于 2016-10-03T13:29:12.780 に答える