Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static const integer class member in header-only file - the proper way?

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).

like image 641
orlp Avatar asked Sep 07 '12 21:09

orlp


1 Answers

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.

like image 121
Cheers and hth. - Alf Avatar answered Sep 19 '22 12:09

Cheers and hth. - Alf