错误C4592:符号将动态初始化。 VS2015.1 static const std :: vector field

时间:2015-12-01 06:26:05

标签: c++ visual-c++ visual-studio-2015

更新VS2015.1后,下一代码不再编译:

class testClass
{
static const std::vector<int> test;
};

初​​始化

const std::vector<int> testClass::test =
{
    1,2
};

有错误:

错误C4592:&#39; test&#39;:符号将动态初始化(实施限制)

是错误还是编译器中发生了某些变化?

4 个答案:

答案 0 :(得分:38)

VC ++编译器dev。

彼得·鲁德曼的答案几乎正确。该警告实际上是指constexpr对象,其中初始化中涉及constexpr构造函数调用。在Update1中,我们现在可以使用constexpr构造函数静态初始化文字类型和一些非文字类型,但不是全部。具体来说,具有虚拟成员函数将阻止静态初始化,即使该类型具有constexpr构造函数并且提供有常量初始化程序。该警告旨在诊断此类病例。不幸的是,当初始化列表中的表达式类型具有constexpr构造函数时,有一个错误导致它触发(在OP的示例中,std :: vector不是&#39;但是std :: initializer_list确实如此) 。可以安全地忽略此警告,因为编译器没有做任何与以前不同的事情。

我们已经修复了这个错误,但遗憾的是发现它包含在Update 1中已经太晚了。无论如何,当我们进行更完整的常量初始化实现时,对此警告的需求应该消失(3.6.2) )。

Tanveer Gani Visual C ++团队。

答案 1 :(得分:9)

不幸的是,我没有足够的“声誉”来评论,所以我会在这里添加我的评论。

@Peter Ruderman:列表中完全支持常量初始化。我还不能说它是否会进入Update 2,但我们会尽力而为。您正在收到没有constexpr构造函数的类型的警告,因为在调用树中检测到不同的 constexpr构造函数的错误。这通常来自std :: initializer_list&lt;&gt;。

@Peter Ruderman:另外,稍微纠正:对于使用constexpr构造函数调用初始化的静态生命周期对象,仅当初始化程序是常量初始化程序时才需要静态初始化,即仅包含常量表达式。 Update1执行此操作但不适用于包含虚函数的类型。

另外:在OP的代码中,不需要静态初始化,但我认为编译器可以出于实现原因的原因进行静态初始化。这是因为使用'const'而不是'constexpr',后者需要静态初始化。

重申:禁用此警告是完全合理的(并且安全)。

答案 2 :(得分:4)

在我的情况下,我通过使用std :: array解决了这个问题,它适用于我,但在一般情况下,我认为警告禁用是解决方案

#pragma warning( disable : 4592)

答案 3 :(得分:1)

相信警告是由新逻辑触发的,用于检测编译器何时使用constexpr构造函数为静态对象生成动态初始值设定项。在这种特殊情况下提高它没有意义,因为std :: vector没有constexpr构造函数。这就是第1号错误。

错误号2是具有constexpr构造函数的静态对象仍然获得动态初始化器。这应该在更新1中修复,但显然微软无法做到。

在模块级别使用constexpr构造函数初始化类型时,编译器应该能够运行构造函数本身并将完全构造的对象直接嵌入到图像文件中。但是,这并不适用于VC。相反,它将创建一个动态初始化程序,并在程序首次启动时在运行时初始化对象。

警告正在尝试显示此问题。在大多数情况下可以安全地忽略,在这种特定情况下忽略它当然是安全的。