了解静态constexpr成员变量
Understanding static constexpr member variables
我对C++11中的static constexpr
成员变量有一些混淆。
在first.hpp
template<typename T>
struct cond_I
{ static constexpr T value = 0; };
// specialization
template<typename T>
struct cond_I< std::complex<T> >
{ static constexpr std::complex<T> value = {0,1}; };
在main()函数中
cout << cond_I<double>::value << endl; // this works fine
cout << cond_I< complex<double> >::value << endl; // linker error
但是,如果我在first.hpp
中添加以下行,一切都会正常工作。
template<typename T1>
constexpr std::complex<T1> cond_I< std::complex<T1> >::value;
我所理解的(我可能错了)是,cond_I< std::complex<double> >::value
需要一个定义,但在前面的情况下,它只有声明。但是cond_I<double>::value
呢?为什么它不需要定义?
同样,在另一个头文件second.hpp
中,我有:
秒
// empty struct
template<typename T>
struct eps
{ };
// special cases
template<>
struct eps<double>
{
static constexpr double value = 1.0e-12;
};
template<>
struct eps<float>
{
static constexpr float value = 1.0e-6;
};
在这种情况下,以下代码在没有任何eps<>::value
定义的情况下可以完美工作。
在main()函数中
cout << eps<double>::value << endl; // works fine
cout << eps<float>::value << endl; // works fine
有人能解释一下static constexpr
成员变量在这些场景中的不同行为吗?
这些行为对于gcc-5.2
和clang-3.6
也是相同的。
根据标准9.4.2/p3静态数据成员[class.Static.data](Emphasis Mine):
如果非易失性const静态数据成员是整型或枚举型,则其在类定义中的声明可以指定大括号或等号初始化器,其中作为赋值表达式的每个初始化器子句都是常量表达式(5.20)。文本类型的静态数据成员可以在具有
constexpr
说明符的类定义中声明;如果是这样的话,它的声明应该指定一个大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定子句都是一个常量表达式。[注:在两者中在这些情况下,成员可能出现在常量表达式中。——结束注释]如果在程序中使用odr(3.2),则成员仍应在名称空间范围中定义,并且名称空间范围定义不应包含初始值设定项
正如M.M之前在评论ostream::operator<<(ostream&, const complex<T>&)
中所解释的那样,该值被认为是程序中使用的odr。因此,根据上述措辞,您必须提供一个定义。
现在,您已经发现基本类型是通过值传递的,这就是为什么不需要定义的原因。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- C++预处理会生成变量成员、资源库和映射
- 局部堆栈变量成员的返回值优化
- Google Mock:在目标类的构造函数中实例化的模拟私有变量成员
- 使用指向结构变量成员的指针访问该结构的成员的地址
- 如果派生类仅包含自动变量成员,是否有必要具有虚拟驱动器
- 线程安全性和静态变量/成员功能
- "static const char array"可以在 C 语言上包含变量成员吗
- 仅用于内部目的的类的所有变量/成员的技术术语是什么
- 如何强制转换变量成员以将其作为函数的引用参数传递
- 类中未声明变量成员函数
- 在 main 中初始化类的 "static const" 类型变量成员的更好方法
- c++模板类静态const变量成员作为映射键给出未定义引用
- 在类中初始化结构变量成员会导致分割错误
- 在c++中建模变量成员类型
- 模板私有静态变量成员的未定义符号
- 不能访问公共静态变量成员
- 常量变量成员在C++有什么用?
- g++ 4.8.2坚持简单变量成员是数组