While experimenting with the recent g++-5 compiler, I wrote below statement in a file:
template<T> T a;
template<> int a = 1;
Which results in:
warning: too many template headers for a
(should be 0)
Also effectively, it doesn't really specialize a<int>
. e.g.
template<typename T> T a;
template<> int a = 1;
int main () {
std::cout << a<double> << "\n"; // prints 0; OK
std::cout << a<int> << "\n"; // prints 0! why not 1?
}
What is the mystery about this syntax?
Template arguments can only be omitted in explicit specialisation of function templates. You have a variable template, so you have to include the <int>
:
template<> int a<int> = 1;
Quoting C++14 (n4140), 14.7.3/10 (emphasis mine):
A trailing template-argument can be left unspecified in the template-id naming an explicit function template
specialization provided it can be deduced from the function argument type.
If you do not want to repeat the type, you can use auto
:
template<> auto a<int> = 1;
[Live example] using Clang.
There's one thing to bear in mind with this: when using auto
, the type of the specialised variable will be deduced from the initialiser, not from the template argument. And since a specialisation can have a different type than the primary template, the compiler will happily accept it even if they differ.