【发布时间】:2013-01-18 09:34:22
【问题描述】:
由于标准的措辞,C++ 中的静态类成员给我带来了一些困惑:
9.4.2 静态数据成员 [class.static.data]
静态数据成员在其类定义中的声明不是定义...
但是,constexpr 需要在其声明(例如,在类定义中)进行初始化(AFAIK,无法从标准中找到引用)。
由于对 constexpr 的限制,我实际上忘记了在类之外定义静态成员的必要性,直到我尝试访问静态 constexpr 数组。 This related question 提供了定义数组成员的正确方法,但我对类模板中此定义的含义感兴趣。
这就是我最终的结果:
template<typename T>
class MyClass
{
private:
static constexpr std::size_t _lut[256] = { /* ... */ };
T _data;
public:
static constexpr std::size_t GetValue(std::size_t n) noexcept
{
return _lut[n & 255];
}
// ...
};
template<typename T>
constexpr std::size_t MyClass<T>::_lut[256];
这是正确的语法吗? 特别是在定义中使用模板感觉很尴尬,但 GCC 似乎正确地链接了所有内容。
作为后续问题,是否应该类似地定义非数组静态 constexpr 成员(在类外使用模板定义)?
【问题讨论】:
-
这里有一件令人困惑的事情:类中的声明不是定义,而是有一个初始化程序。类外的声明没有初始化器,而是一个定义。
-
这令人困惑(至少恕我直言),但 constexpr 规范要求初始化程序位于声明点,而不是定义点。大概这与根据 ODR 处理常量表达式的方式有关(即 constexpr 成员不需要定义,只要它仅用于编译时常量表达式 - 请参阅 ecatmur 给出的答案) .
标签: c++ templates c++11 static-members constexpr