c++c++17

Define static constexpr native array member outside of class


The following code works just fine with s_digitU2s defined in class:

#include <iostream>

class Foo {
public:
    template <class Index>
    static constexpr const char* digitU2(const Index a) {
        return s_digitU2s[a];
    }

private:
    static constexpr const char* s_digitU2s[100] = {
        "00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
        "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
        "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
        "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
        "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
        "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
        "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
        "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
        "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
        "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"
    };
};

int main() {
    std::cout << Foo::digitU2(42) << std::endl;
    return 0;
}

However I would like to define s_digitU2s outside of Foo essentially to tuck it out of sight (in a "header implementation file" my header file will include after Foo is defined). I will also be making 3 and 4 digit members (with 1,000 and 10,000 elements respectively) and they would even further clutter Foo

I am using C++17 and not finding the syntax needed to define a static constexpr native array member outside a class


Solution

  • You can declare a static data member without constexpr, then define it with constexpr outside the class:

    class Foo {
        // ...
    private:
        static const char* const s_digitU2s[100];
    };
    
    inline constexpr const char* Foo::s_digitU2s[100] = { /* ... */ };
    

    Note that the in-class declaration must have the correct type. Because constexpr attaches to the variable as a whole and makes it const, the type of s_digitU2s in its definition is "array of 100 const const char*s", i.e., "array of 100 const char* consts".

    (You can define the function digitU2 in the class definition, just like you're doing now. But if for some reason you need to separate the declaration and definition, be aware that the rules for functions are different from the rules for variables. For a constexpr function, all declarations of the function must be constexpr, but you're allowed to have forward declarations.)