我有这样的代码:
class A
{
public:
unsigned long a;
static const unsigned long b = sizeof(a); // "error C2327: 'A::a' : is not a type name, static, or enumerator" in VC++
};
我在VC ++中遇到编译错误,IAR没有错误。哪个编译器是正确的,C ++标准中说的是什么?
您的MSVS版本已经很老了,所以基于此,假设它们默认为C ++ 03,它们拒绝您的代码是正确的。我引用n1905,这对我们来说非常接近C ++ 03标准。
9.4 [class.static](强调我的)
如果在成员的declarator-id之后的静态成员的定义中使用了unqualified-id(5.1),并且name lookup(3.4.1)发现unqualified-id引用静态成员,枚举器或嵌套类型在成员的类(或成员类的基类)中,unqualified-id被转换为qualified-id表达式,其中nested-name-specifier命名从中引用成员的类作用域。静态成员的定义不应直接使用其类的非静态成员的名称或其类的基类的名称(包括作为sizeof运算符的操作数)。静态成员的定义可能只引用这些成员来形成成员指针(5.3.1)或类成员访问语法(5.2.5)。
StoryTeller's answer说明了为什么这对visual-studio-2005不起作用。也就是因为它直到c++11才得到支持。
至于visual-studio-2013,它不完全符合c++11。但我已经验证了这段代码可以解决这个问题:
static const unsigned long b = sizeof(decltype(a))
如果你想要的东西也适用于visual-studio-2005,可以考虑让b
成为全局的,而不是A
的静态成员:
const unsigned long b = sizeof(A().a)
使用非static
成员的qazxsw poi qazxsw poi-qualified成员类内初始化程序在C ++ 11之前不是C ++标准的一部分。
最早支持C ++ 11的MSVC编译器是MSVC2017。
该编译器将正确编译您的代码。
你有一个名为const
的static
的定义。
你的班级有一个名为class
的A
。
你的班级有一个名为unsigned long
的a
。
在某些C ++编译器中,static const unsigned long
的静态和非静态成员不能混合,特别是在定义阶段。
b
这不是你想要的,但这是智能编译器试图弄清楚的。
因为静态成员不会将其范围限制为对象定义。它们跨越对象范围,可以从任何地方访问,只需使用class
在控制台中输出static const unsigned long b = sizeof(unsigned long);
。
Clang不接受这种结构,GCC(不论是A::b
)
MSVC 19.14(visual studio 15.7)也不接受它,但视觉工作室15.8,MSVC 19.15,确实如此。
谨慎选择。
在这里,我检查了很多编译器:std::cout << A::b << std::endl
这是一种方法,但你必须在将来规避这种黑客攻击。
责备部分是混合C和C ++。它仅适用于没有任何检查的旧版本的编译:
-g -std=c++98