当前位置:  开发笔记 > 编程语言 > 正文

了解静态constexpr成员变量

如何解决《了解静态constexpr成员变量》经验,为你挑选了1个好方法。

我对static constexprC++ 11中的成员变量有一些疑惑.

在first.hpp中

template
struct cond_I
{ static constexpr T value = 0; }; 


// specialization 
template
struct cond_I< std::complex >
{ static constexpr std::complex value = {0,1}; }; 

在main()函数中

cout << cond_I::value << endl;            // this works fine
cout << cond_I< complex >::value << endl; // linker error

但是,如果我添加以下行,first.hpp一切正常.

template 
constexpr std::complex cond_I< std::complex >::value;

我理解的(我可能是错的)是,cond_I< std::complex >::value需要一个定义,但在前一种情况下它只有声明.但那又怎么样cond_I::value?为什么它不需要定义?

再次,在另一个头文件中second.hpp,我有:

在second.hpp中

// empty struct
template
struct eps
{ };


// special cases
template<>
struct eps
{
  static constexpr double value = 1.0e-12;
};

template<>
struct eps
{
  static constexpr float value = 1.0e-6;
};

在这种情况下,以下代码完美无需任何定义eps<>::value.

在main()函数中

cout << eps::value << endl;    //  works fine
cout << eps::value << endl;     //  works fine

有人可以static constexpr在这些场景中向我解释成员变量的不同行为吗?

对于gcc-5.2和,这些行为也是相同的clang-3.6.



1> 101010..:

根据标准9.4.2/p3静态数据成员[class.static.data](Emphasis Mine):

如果非易失性const静态数据成员是整数类型或枚举类型,则其在类定义中的声明可以指定一个大括号或大小为初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式(5.20) ).可以使用说明constexpr符在类定义中声明文字类型的静态数据成员; 如果是这样,它的声明应指定一个大括号或等于初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式.[注意:在这两种情况下,成员可能会出现在常量表达式中. - 结束注释]如果程序中使用了odr-used(3.2),并且命名空间作用域定义不包含初始化程序,则仍应在名称空间作用域中定义该成员.

正如MM先前在评论中所解释的那样,ostream::operator<<(ostream&, const complex&)通过引用传递,因此该值被认为是在程序中使用的.因此,正如上面的措辞所规定的那样,你必须提供一个定义.

现在你已经发现基本类型是按值传递的,这就是为什么不需要定义的原因.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有