Reputation: 483
If I have: a.hpp a.cpp and main.cpp includes a.hpp, and in a.hpp I write
template<typename T>
constexpr int num;
template<>
constexpr int num<float> = 1;
template<>
constexpr int num<double> = 2;
Do I risk defining the variable num multiple times both in a.o and main.o? Or is it declared inline? Shall I put template variables specializations inside a.cpp? What changes if I wrap a.hpp into a namespace?
Upvotes: 0
Views: 464
Reputation: 26342
Do I risk defining the variable
num
multiple times both in a.o and main.o?
You do. For non-template variables, constexpr
implies const
and const
at the namespace level implies internal linkage, but not for variable templates. It seems that this is underspecified in the standard. The current draft has the following
Note 1: An instantiated variable template that has
const
-qualified type can have external or module linkage, even if not declaredextern
.
Experimentally, different compilers give them different linkages. For example, with GCC 9.3.0 and 10.2.0 num<float>
has internal linkage:
nm -C a.o ... 0000000000000004 r num<float>
but with Clang 10.0.0 it has external linkage:
nm -C a.o ... 0000000000000000 R num<float>
As a result, if you try to include a.hpp
in two compilation units, you'll get a link error with Clang.
Or is it declared inline?
No, explicit inline
is needed.
What changes if I wrap a.hpp into a namespace?
I guess you're talking about an unnamed namespace. In this case each compilation unit is guaranteed to get its own (private) copy.
Upvotes: 1