请考虑以下代码:
#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 compiles it,只是警告未使用的变量。
然而,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中的错误,还是我错过了一些基本的东西?
答案 0 :(得分:5)
这是MSVC中的一个错误。
C ++ 11/14允许在非评估的上下文中使用非静态类成员,参见5.1.1 [expr.prim.general] p。 13:
表示非静态数据成员或类的非静态成员函数的id表达式只能用于:
...
(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
,这是一种完全无法解释的行为。我不知道除了一个错误之外它是怎么回事。
clang ++ like g ++ in C ++ 11 and C ++ 14 mode接受该程序。 c ++ 03模式下的clang ++拒绝所有4个M
的引用(C ++ 03没有像第13.3页那样),而C ++ 03模式中的g ++仍然接受它们(这可能是g ++ C ++ 03模式bug)。