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 表达式:

...

(13.3) — 如果该 id 表达式表示一个非静态数据成员并且它出现在未计算的操作数中。

[ 例子:

    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 没有类似第 13.3 页的任何内容),而 C++03 模式下的 g++ 仍然接受它们(这可能是 g++ C++03 模式漏洞)。

于 2016-10-03T13:29:12.780 回答