如何定义静态常量成员?

7

我的 Test 类有一个子类型的 const static 成员。我通常将这个 const static 成员定义为如下所示。

class Test 
{
public:
    class Dummy {};

private:
    static Dummy const dummy;

};

Test::Dummy const Test::dummy;             // ERROR HERE

int main() 
{
    return 0;
}

使用gcc-4.6编译时,没有错误,可以正确编译。

但是,如果使用gcc-4.4编译相同的源代码,则会出现以下错误: error: uninitialized const ‘Test::dummy’ 在标记的行上。

  • 是否有其他定义静态常量成员变量的方法?
  • 这是gcc-4.4的限制吗?
  • 是否有解决方法?

2
Test::Dummy const Test::dummy = Test::Dummy(); - Sergey Kalinichenko
4个回答

6

说:

Test::Dummy const Test::dummy = { };

1
只要 Test::Dummy 是聚合体(C++03),或者总是在 C++11 中,就应该可以工作。 - Kerrek SB

2
请参见http://gcc.gnu.org/wiki/VerboseDiagnostics#uninitialized_const(其中提供了与标准相关的参考资料),以及GCC 4.6 release notes,其中提到:
在4.6.0和4.6.1版本的G++中,除非类型具有用户声明的默认构造函数,否则不再允许将const限定类型的对象进行默认初始化。在4.6.2版本的G++中,实现了DR 253 的建议解决方案,因此如果默认初始化了所有子对象,则允许默认初始化。编译失败的代码可以通过提供初始化器来修复,例如:
struct A { A(); };
struct B : A { int i; };
const B b = B();

使用-fpermissive选项来允许旧的,不符合标准的行为。

1

你也可以为 class Dummy 添加一个默认构造函数:

class Dummy { public: Dummy(){} };

第4行。

编辑: 看起来gcc 4.4无法为类Dummy生成默认构造函数。因此,上述代码直接解决了这个编译器的错误。


1
不需要,Dummy有一个编译器合成的默认构造函数。 - juanchopanza
@juanchopanza,在gcc 4.3.2下,上述方法解决了问题,而且没有对原始代码进行任何其他更改。 - Walter
@juanchopanza 确实,这是一个编译器的 bug:gcc 4.3.2(和 4.4)无法生成默认构造函数。但这意味着添加默认构造函数确实可以从根本上解决问题! - Walter
GCC不会无法生成默认构造函数,标准不允许在那里使用它,请参见http://gcc.gnu.org/wiki/VerboseDiagnostics#uninitialized_const。 - Jonathan Wakely
@Jonathan Wakely这是否意味着juanchopanza上面的第一条评论是错误的? - Walter
显示剩余2条评论

0

使用gcc 4.4,使用以下命令:

Test::Dummy const Test::dummy = Test::Dummy;

使用支持C++11的编译器,您可以使用统一初始化语法:

Test::Dummy const Test::dummy = { };

但我认为gcc 4.4不支持这个。


你的第一个解决方案在gcc 4.3.2上不起作用,但第二个(a la Kerrek SB)可以。 - Walter
第一个应该使用 Test::Dummy() 而不是 Test::Dummy。对于第二个,统一初始化语法应该没有 =,即 Test::Dummy const Test::dummy{ }; - Jonathan Wakely

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接