【问题标题】:Static Constant Class Members静态常量类成员
【发布时间】:2009-02-23 18:04:17
【问题描述】:

考虑以下 sn-p:

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

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

在这种情况下,标准是否要求我们在翻译单元中显式声明 value?看来我有相互矛盾的信息; boost 和 STL 中的 numeric_limits 之类的东西似乎就像在我的 sn-p 中一样做这种事情。

OTOH,我记得在某处(尽管很久以前)读到过,您仍然需要在翻译单元中提供声明。

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

我很感激你的 cmets 什么是“正确的方法”。

【问题讨论】:

    标签: c++


    【解决方案1】:

    你也必须在翻译单元中提供一个定义,以防你使用值变量。这意味着,例如,如果您读取它的值。

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

    在下一个 C++ 标准版本中,规则发生了变化。变量在用作常量表达式时使用。只需阅读上面直接在类中初始化变量的 value 意味着那时仍然不需要定义。

    参见标准3.2 One Definition Rule 部分中use 的定义以及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。然而,这是相当理论的东西,因为大多数(全部?)编译器无论如何都不会抱怨。感谢评论区的小哥告诉我。

    【讨论】:

    • 所以,为了澄清,例如 numeric_limits 的作用在技术上是“非法的”吗?可能是我误会了……
    • 是的。一旦违反,该标准不再对实施提出要求。编译器可能会拒绝它,也可能会接受它。由它决定。但是你怎么知道你的编译器没有提供定义?请注意,您必须查看实现文件。 .h 文件没有定义。
    • 好吧,我通过简单地包含标准限制标头进行测试,并生成预处理输出。 MSVC(9,如果重要的话)的实现没有定义任何 numeric_limits 专业化之外的任何静态常量成员。甚至 Comeau 的编译器也能毫无问题地吃掉这个 sn-p。
    • 是的。实际上,该定义已放入库中,每个都有一个确切的定义。否则,如果您多次包含 ,您将获得多个定义,这直接违反了一个定义规则。
    • 如果 T 来自 int 系列,那么您不必提供定义,只要您不尝试获取该成员的地址或以某种需要的方式使用它存储。
    【解决方案2】:

    补充 litb 所说的内容,来自我的 n2798 副本:

    9.4.2

    [...]

    2 静态数据成员在其类定义中的声明不是定义和
    可能是除 cv 限定的 void 以外的不完整类型。静态的定义
    数据成员应出现在包含该成员的类定义的命名空间范围内。在 命名空间范围内的定义,静态数据成员的名称应被限定 使用 :: 运算符按其类名。

    【讨论】:

      【解决方案3】:

      如果您不以某种需要将它们存储在内存中某处的方式使用它们(例如,获取此类成员)。请参阅 Stroustrup 的 C++ 编程语言,第 10.4.6.2 节。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多