静态常量类成员

时间:2009-02-23 18:04:17

标签: c++

请考虑以下代码段:

struct Foo
{
    static const T value = 123; //Where T is some POD-type
};

const T Foo::value; //Is this required?

在这种情况下,标准是否要求我们在翻译单元中明确声明?我似乎有相互矛盾的信息;像STL中的numeric_limits这样的提升似乎就像在我的代码片段中那样做。

OTOH,我记得在某个地方(虽然很久很久以前)仍然需要在翻译单位提供声明。

如果是这种情况,那么模板专业化呢?每个专业都需要声明吗?

我很感激您对“正确方法”的看法。

3 个答案:

答案 0 :(得分:3)

如果使用值变量,您还必须在翻译单元中提供定义。这意味着,例如,如果您读取其值。

重要的是,如果违反该规则,编译器不需要发出警告或错误。标准说“违规无需诊断”。

在下一个C ++标准版本中,规则已更改。当变量用作常量表达式时,变量 not 。只需读取上面直接初始化变量的 value ,就意味着仍然不需要定义。

请参阅标准use部分中3.2 One Definition Rule的定义和9.4.2, paragraph 4 and 5中静态数据成员定义的要求(在C ++ 98标准中。出现在段落中) n2800下一个标准草案中的3和4)。

更正: c ++ 03的规则已经更改:如果变量出现在需要整数常量表达式的位置,则不需要定义(引用2003年更新的非官方修订列表) ,请参阅this language defect report的决议:

  

表达式可能被评估,除非它出现在需要整数常量表达式的地方(见5.19),是sizeof运算符的操作数(5.3.3),或者是typeid运算符的操作数而表达式没有指定多态类类型的左值(5.2.8)...

请注意,即便如此,许多用途仍然是所需的积分常数。其中一个是数组维度或模板元编程的情况。严格来说(参见this report),只有c ++ 1x解决方案才能真正保证在明显的情况下也像"s == string::npos"一样,其中一个整数常量不是所需的定义不需要静态成员,因为下一个标准有一个不同的,更好的措辞3.2。然而,这是非常理论化的东西,因为大多数(全部?)编译器都不会呻吟。感谢评论部分的人告诉我。

答案 1 :(得分:1)

从我的n2798副本中添加litb所说的内容:

  

<强> 9.4.2

     

[...]

     

2在类定义中声明静态数据成员不是定义和
   可能是除了cv-qualified void之外的不完整类型。静态的定义
   数据成员应出现在包含成员类定义的命名空间范围内。在    在命名空间范围内的定义,静态数据成员的名称应该是合格的    通过使用:: operator。

的类名

答案 2 :(得分:0)

如果你不以某种方式使用它们,那么你不必为静态整数常量成员提供定义,这需要将它们存储在某个地方的内存中(例如,取这样的地址)成员)。请参阅Stroustrup的 The C ++ Programming Language ,第10.4.6.2节。

编辑: 哎呀,我刚刚重新阅读了这个问题,问题是针对某些类型的T.一般来说,你需要提供一个定义,我同意。但是,如果您使用int系列中的某些内容,则不一定非必要(有上述警告)。