我有这样的代码:
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 ++标准对此有何评论?
答案 0 :(得分:1)
您的MSVS版本很旧,因此基于此版本,并假设它们默认为C ++ 03,那么拒绝您的代码是正确的。我引用n1905,出于我们的目的,它非常接近C ++ 03标准。
9.4 [class.static] (强调我的意思)
如果在静态变量的定义中使用了非限定ID(5.1) 成员的声明者ID和名称查找之后的成员(3.4.1) 发现unqualified-id指向静态成员枚举器, 或成员类的嵌套类型(或 成员的班级),将不合格ID转换为合格ID 嵌套名称说明符用于命名类作用域的表达式 从中引用成员。 静态成员的定义 不得直接使用其非静态成员的名称 类或该类的基类(包括作为 sizeof运算符)。静态成员的定义只能引用 这些成员形成指向成员(5.3.1)或与类的指针 成员访问语法(5.2.5)。
答案 1 :(得分:1)
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)
答案 2 :(得分:0)
您具有名为class
的{{1}}的定义。
您的班级具有名为A
的{{1}}。
您的班级具有名为unsigned long
的{{1}}。
在某些C ++编译器中,a
的 static 和 non-static 成员不能混合使用,特别是在定义阶段。
static const unsigned long
这不是您想要的,但这是智能编译器试图找出的方式。
因为静态成员不会将其范围限制为对象定义。它们超出了对象范围,例如,可以使用b
在控制台中只需输出class
就可以从任何地方访问它们。
Clang不接受这种构造,GCC接受(都带有static const unsigned long b = sizeof(unsigned long);
)
MSVC 19.14(Visual Studio 15.7)也不接受,但是带有MSVC 19.15的Visual Studio 15.8接受。
仔细选择。
我在这里检查了很多编译器:https://godbolt.org/ 这是一种方法,但是您将来必须回避此类黑客攻击。
最怪的部分是混合使用C和C ++。它仅适用于未经检查的旧版本:
A::b
答案 3 :(得分:0)
static
成员的 const
static
合格成员类初始化器直到C ++ 11才成为C ++标准的一部分。
最早完全支持C ++ 11的MSVC编译器是MSVC2017。
该编译器将正确编译您的代码。