静态const成员初始化中的sizeof

时间:2018-11-28 13:19:58

标签: c++ visual-studio-2013 visual-studio-2005 sizeof member-variables

我有这样的代码:

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 ++标准对此有何评论?

4 个答案:

答案 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指定为什么此功能不适用于。这是因为直到才支持。

而言,它完全 不兼容。但我已验证此代码可解决该缺陷:

static const unsigned long b = sizeof(decltype(a))

如果您还希望某些东西可以与一起使用,请考虑将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。

该编译器将正确编译您的代码。