Please consider the below program:
FILE A.H
template <typename T> struct C { static constexpr int x = 42; };
FILE B.H
#include "A.H"
template <> struct C<int> { static constexpr int x = 43; };
FILE A.CC
#include "A.H"
void a() { std::cout << C<int>::x; }
FILE B.CC
#include "B.H"
void b() { std::cout << C<int>::x; }
FILE MAIN.CC
void a(); void b();
int main() { a(); b(); }
What is the status of this program? Is it ill-formed, ill-formed with no diagnostic required, does it exhibit undefined behaviour, or none of the above (its okay)?
If none of the above, what is the output of the program?
If one of the above, what rule does it violate?
(Also, would the answer be different if B.H contained a partial specialization rather than an explicit specialization?)
This is [temp.arg.template]/2:
If a specialization is not visible at the point of instantiation, and it would have been selected had it been visible, the program is ill-formed, no diagnostic required.
The specialization for C<int>
isn't visible in the definition of a()
, but would've been selected if it had been.
But more importantly, this is the limerick (spacing mine):
When writing a specialization,
be careful about its location;
or to make it compile
will be such a trial
as to kindle its self-immolation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With