如何在 C++ class 中定义编译时(静态)常量?

How to define compile-time (static) constant inside a C++ class?

我有一些常量只需要在编译时使用以简化代码,所以我不需要在运行时可用的实际变量。

传统上这样做的方式是 #define NAME 123 但我想要一个类型安全的替代方案。

在 classes 之外你可以 const int name = 123; 这很好用,但似乎不可能把它放在 class 里面。例如:

class Example {
    public:
        const double usPerSec = 1000000.0;
};
double usOneMinute = 60 * Tempo::usPerSec;

适用于 Visual C++,但不适用于 GCC:

error: non-static const member ‘const double Example::usPerSec’,
  can’t use default assignment operator

您可以通过将其设为静态来修复它,但随后 Visual C++ 会报错:

error C2864: 'Example::usPerSec' : a static data member with an in-class
  initializer must have non-volatile const integral type
    type is 'const double'

我猜这意味着 VC++ 将只接受 static const int.

我想避免在构造函数中设置值,因为那样我需要在运行时 class 的实例才能访问该值,而实际上我希望在编译时像现在这样处理它#define.

那么我如何在 class 中将常量定义为 double,而不求助于使其成为全局变量或使用 #define,这将在没有实例的情况下工作class,这将适用于主要的 C++03 编译器?

此代码适用于 vc++ 和 gcc :

class Example {
public:
    static const double usPerSec ;
};
const double Example::usPerSec=10000.0;
double usOneMinute = 60 * Example::usPerSec;

我看到了两种可能的 C++03 方法:

  1. 使用静态成员函数并依赖内联:

    class Example {
        public:
            static double usPerSec() { return 1000000.0; }
    };
    double usOneMinute = 60 * Example::usPerSec();
    
  2. 使用静态数据成员并退出常量折叠(使用常量的值将在运行时计算):

    class Example {
        public:
            static const double usPerSec;
    };
    double usOneMinute = 60 * Example::usPerSec;
    
    // Somewhere in one .cpp
    const double Example::usPerSec = 1000000.0;
    

你必须让它成为静态常量,然后在 class 之外给它赋值。不要在构造函数中这样做。你不必制作实例

class Example {
public:
    static const double usPerSec;

};

double Example::usPerSec = 1000000.0;

现在您可以在任何地方使用它而无需创建 class

的任何实例
double someVar = Example::usPerSec;

这里积分和其他类型是有区别的。对于整数类型,您始终可以将它们定义为 const static 成员,如

struct Example
{
    const static int name = 123;  // added 'static' to code in text of question
    const static unsigned usPerSec = 1000000;
};

对于非整数类型,比如你例子中的double,情况就比较复杂了。自 2011 年以来(对大多数编译器使用编译器选项 std=c++11),您可以简单地这样做:

struct Example
{
    constexpr static double usPerSec = 1000000.0;
};

但是对于 gcc,这

struct Example
{
    const static double usPerSec = 1000000.0;
};

应该也适用于 C++03(它是 GNU 扩展)。

然而,C++03 中的标准方法,也被标准库本身使用(例如在 std::numeric_limits<> 中),是一个 static 成员函数

struct Example
{
    static double usPerSec() { return 1000000.0; }
};

如果我是你,我会把它放在命名空间中:

namespace MyExampleNamespace {
    const double usPerSec = 1000000.0;
}
double usOneMinute = 60 * MyExampleNamespace::usPerSec;