如何在 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 方法:
使用静态成员函数并依赖内联:
class Example {
public:
static double usPerSec() { return 1000000.0; }
};
double usOneMinute = 60 * Example::usPerSec();
使用静态数据成员并退出常量折叠(使用常量的值将在运行时计算):
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;
我有一些常量只需要在编译时使用以简化代码,所以我不需要在运行时可用的实际变量。
传统上这样做的方式是 #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 方法:
使用静态成员函数并依赖内联:
class Example { public: static double usPerSec() { return 1000000.0; } }; double usOneMinute = 60 * Example::usPerSec();
使用静态数据成员并退出常量折叠(使用常量的值将在运行时计算):
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;