1

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

DarthRubik
  • 3,927
  • 1
  • 18
  • 54
  • Can you show a [MCVE] where `extern` is actually needed? – πάντα ῥεῖ Jun 04 '16 at 15:58
  • 1
    @πάνταῥεῖ With the code I have posted my compiler complains if it is not `extern`: `'value' is not a valid template argument for type 'const float&' because object 'value' has not external linkage` (I am using `gcc`) – DarthRubik Jun 04 '16 at 15:59
  • 1
    GCC has yet to update to the C++11 rules in this area. – T.C. Jun 04 '16 at 16:03
  • @T.C. I looked at that question.....it does not actually answer anything about *parameters*...it talks about the actual `template`s themselves being externally linked – DarthRubik Jun 04 '16 at 16:05
  • @t.c. that dupe is a narrow issue with internal linkage of functions called from within template adl it looks like. Does not answer this question? If it does, it flew over my head! – Yakk - Adam Nevraumont Jun 04 '16 at 16:32

1 Answers1

4

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.

Barry
  • 286,269
  • 29
  • 621
  • 977
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524