在C++中的类声明中初始化const成员

ezp*_*sso 74 c++ g++

在PHP和C#中,常量可以在声明时初始化:

class Calendar3
{
    const int value1 = 12;
    const double value2 = 0.001;
}
Run Code Online (Sandbox Code Playgroud)

我有一个仿函数的以下C++声明,它与另一个类一起使用来比较两个数学向量:

struct equal_vec
{
    bool operator() (const Vector3D& a, const Vector3D& b) const
    {
        Vector3D dist = b - a;
        return ( dist.length2() <= tolerance );
    }

    static const float tolerance = 0.001;
};
Run Code Online (Sandbox Code Playgroud)

这个代码编译没有问题与g ++.现在在C++ 0x模式(-std = c ++ 0x)中,g ++编译器输出一条错误消息:

错误:'constexpr'需要对非整数类型的静态数据成员'容差'进行类内初始化

我知道我可以static const在类定义之外定义和初始化该成员.此外,可以在构造函数的初始化列表中初始化非静态常量数据成员.

但有没有办法在类声明中初始化一个常量,就像在PHP或C#中可能的那样?

更新

我使用static关键字只是因为可以在g ++中的类声明中初始化这些常量.我只需要一种方法来初始化类声明中的常量,无论它是否声明static.

Ant*_*ams 124

在C++ 11中,可以在类声明中初始化非static数据成员,static constexpr数据成员以及static const整数或枚举类型的数据成员.例如

struct X {
    int i=5;
    const float f=3.12f;
    static const int j=42;
    static constexpr float g=9.5f;
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,i类的所有实例的成员X初始化为5由编译器生成的构造,并且f部件被初始化为3.12.的static const数据成员j初始化为42,将static constexpr数据成员g初始化为9.5.

由于float并且double不是整数或枚举类型,因此这些成员必须是constexpr或不static按顺序允许类定义中的初始化程序.

在C++ 11之前,只有static const整数或枚举类型的数据成员可以在类定义中使用初始值设定项.

  • 我想知道为什么是“static const int”而不是“static constexpr float”?“float 和 double 不是整型或枚举类型”是什么意思? (2认同)
  • 这个限制有什么意义呢?无论如何,感谢您的好回答 (2认同)

Flo*_*ian 44

初始化除const int类型之外的静态成员变量不是标准C++之前的C++ 11.除非您指定-pedantic选项,否则gcc编译器不会向您发出警告(并生成有用的代码).然后你应该得到一个类似的错误:

const.cpp:3:36: error: floating-point literal cannot appear in a constant-expression
const.cpp:3:36: warning: ISO C++ forbids initialization of member constant ‘tolerance’ of non-integral type ‘const float’ [-pedantic]
Run Code Online (Sandbox Code Playgroud)

这样做的原因是C++标准没有规定应该如何实现浮点并留给处理器.为了解决这个问题constexpr并引入了其他限制.


Sti*_*sis 11

是.只需添加constexpr关键字,如错误所示.

  • 他提到的问题是由于他试图编译为C++ 11而引入的,即他希望支持C++ 11 :) (5认同)
  • 也许他不想为他的项目要求 C++11? (2认同)