I am asking myself why the following code works and what the specifier extern does when instantiating baz_instance:
struct baz {
int value;
};
extern const baz baz_instance = {3};
template<baz const& b>
int foo(){
return b.value;
}
int main(){
foo<baz_instance>();
return 1;
}
Why does the above code compile in the first place and why doesn't it compile anymore if the extern specifier is left out? What does the extern specifier do in this example?
This is one of the parts of the standard that changed from C++03 to C++11.
In C++03, [temp.arg.nontype] reads:
In C++11, that got updated as a result of issue 1155, though GCC still has a bug with regards to this behavior:
In C++14, that got simplified even further and doesn't even mention linkage.
As to your specific question, the
externspecifier adds external linkage tobaz_instance. Without it,baz_instancehas internal linkage. In C++03, you needed external linkage to have a non-type template parameter of reference type. In C++11, you don't anymore - soexternis no longer necessary and it compiles fine without it.