Search code examples
c++templatesexternnon-type

Why do you need external linkage for references to non-type template arguments


Suppose I have the struct:

template<const float& myFloat>
struct Thing{ };

Later to declare it I have to do this:

extern constexpr float value = 12.0f;
Thing<value> MyThing;

Why does this need the extern keyword. I mean it should not matter whether or not the float is extern or not (should it?)


Solution

  • Suppose your code is in a header file somewhere.

    As it happens, Thing also has an operator(), and it is stored in a std::function in two different cpp files.

    Someone gets the typeids out of the two std::functions and asks if they are equal.

    With external linkage on the float, they are clearly the same type. Without, there is no way to express they are.

    Basically, the type is dependent on the identity not the value of the float, and only extern linkage globals have identity at the same "level" as the standard wants such types to have.

    Now the same can be said of lambdas, but lambdas lead to ODR violations extremely often.