Say I have the following example:
#include <cstdlib>
class A {
public:
static const std::size_t value = 42;
};
In short, I have (or better, want) a class A
with a static const std::size_t
member called value
with the value 42
(determined at compile time).
Now, IIRC, this only works fine under certain circumstances. It doesn't, for example, when you take the address of A::value
. In order for this to work fine in all cases you'd need to add a definition in some implementation file:
const std::size_t A::value;
However, I can't do this, because I want this file to be header-only. Another common solution is this:
class A {
public:
enum { value = 42 };
};
I don't like this solution either, because I'd like the type of A::value
to be std::size_t
.
What is a good solution to this problem? Preferably a small and portable solution, not something with huge macro magic like BOOST_STATIC_CONSTANT
.
I'd like a solution for C++03, not C++11 (it's trivial there).
First of all, using the unsigned size_t
type for numbers, you're likely to run into implicit promotion problems. So, good idea to use its corresponding signed type, which is called ptrdiff_t
. Which, as it happens, is the result type of a pointer difference expression.
Also, due to changes in C++11, it’s generally a good idea to include <stddef.h>
and not <cstddef>
, i.e., write ::ptrdiff_t
or just plain ptrdiff_t
, not std::ptrdiff_t
.
Now, here's how to do the header file extern linkage constant thing:
template< class Dummy >
struct A_constants_
{
static ::ptrdiff_t const value;
};
template< class Dummy >
::ptrdiff_t const A_constants_<Dummy>::value = 42;
typedef A_constants_<void> A_constants;
class A
: public A_constants
{
public:
// Whatever
};
Then you can use it like this:
foo( A::value );
There are also some other ways of doing this, but the above is about the simplest and easiest to get right.
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