Search code examples
c++c++17compile-time-constant

Where to define compile-time constants?


I made a super simple design to start solving a problem.

enter image description here

Now, this might seem like super trivial at first, but since there are tons of ways to do this, it confuses me, due to my lack of professional experience.

Where would I define those compile time constants? (Always suppose I'm using the highest current C++ standard version)

In a namespace? Inside the class? In a .h outside the class? In the .cpp outside the class? Just use them as magic numbers and add some comment? static? non-static? const? constexpr? template the deck size in case its bigger?

What I thought of:

class JolloManager
{
private:
    constexpr static int rounds = 3;
    constexpr static int deckSize = 52;
    constexpr static int princeId = 1;
    constexpr static int princessId = 2;
    std::array<int, deckSize> deck;
public:
    JolloManager() {};
};

Is this correct?


Solution

  • In C++17, defining compile-time integer constants is easy.

    First, you should decide whether or not the constant should be scoped to a class. If it makes sense to have it as a class member (e.g., it pertains to the concept that the class represents) then make it a class member. Otherwise, don't.

    As a class member, write:

    class JolloManager {
        constexpr static int rounds = 3;
    };
    

    That's it. No out-of-line definition is required anymore in C++17.

    If it's not going to be a class member, but you want everyone who includes your header to be able to access the value, then write this in the header:

    inline constexpr int rounds = 3;
    

    (Technically, the reason to use inline is to avoid ODR violations when the variable is ODR-used by an inline function in multiple translation units.)

    If the value is an implementation detail that only one .cpp file needs access to, then write the following in that .cpp file to give it internal linkage (i.e., prevent clashing with names in other translation units):

    constexpr int rounds = 3;  // no `inline` this time
    

    Finally, if the constant is only needed by a single function, you can make it local to that function:

    void foo() {
        constexpr int rounds = 3;
    }