I have some constants that only need to be used at compile-time to simplify code, so I don't need the actual variables available at runtime.
Traditionally the way this was done was with #define NAME 123
but I would like a type-safe alternative.
Outside of classes you can const int name = 123;
which works fine, but it doesn't seem possible to put this inside a class. For example this:
class Example {
public:
const double usPerSec = 1000000.0;
};
double usOneMinute = 60 * Tempo::usPerSec;
Works with Visual C++, but doesn't work with GCC:
error: non-static const member ‘const double Example::usPerSec’,
can’t use default assignment operator
You can fix it by making it static, but then Visual C++ complains:
error C2864: 'Example::usPerSec' : a static data member with an in-class
initializer must have non-volatile const integral type
type is 'const double'
I'm guessing this means VC++ will only accept static const int
.
I want to avoid setting the value in the constructor because then I need an instance of the class at runtime in order to access the value, whereas really I want it all handled at compile time like it is with #define
.
So how can I define a constant as a double
inside a class, without resorting to making it global or using #define
, that will work without having an instance of the class, and that will function with major C++03 compilers?
There is a difference here between integral and other types. For integral types you can always define them as const static
members as in
struct Example
{
const static int name = 123; // added 'static' to code in text of question
const static unsigned usPerSec = 1000000;
};
For non-integral types, such as double
in your example, the situation is more complicated. Since 2011 (using compiler option std=c++11
with most compilers), you can simply do this:
struct Example
{
constexpr static double usPerSec = 1000000.0;
};
But with gcc, this
struct Example
{
const static double usPerSec = 1000000.0;
};
should work also in C++03 (it's a GNU extension).
However, the standard approach in C++03, which is also used by the standard library itself (for example in std::numeric_limits<>
), is a static
member function
struct Example
{
static double usPerSec() { return 1000000.0; }
};
I see two possible approaches with C++03:
Use a static member function and rely on inlining:
class Example {
public:
static double usPerSec() { return 1000000.0; }
};
double usOneMinute = 60 * Example::usPerSec();
Use a static data member and resign on constant folding (the value using the constant will be computed at runtime):
class Example {
public:
static const double usPerSec;
};
double usOneMinute = 60 * Example::usPerSec;
// Somewhere in one .cpp
const double Example::usPerSec = 1000000.0;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With