Экспериментируя с недавним компилятором g ++ — 5, я записал в файл следующее утверждение:
template<T> T a;
template<> int a = 1;
Что приводит к:
предупреждение: слишком много заголовков шаблонов для
a
(должно быть 0)
Также эффективно, это не действительно специализируется a<int>
, например
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?
}
В чем загадка этого синтаксиса?
Аргументы шаблона могут быть опущены только при явной специализации функция шаблоны. У вас есть шаблон переменной, поэтому вы должны включить <int>
:
template<> int a<int> = 1;
Цитирование C ++ 14 (n4140), 14.7.3 / 10 (выделено мной):
Трейлинг Шаблон-аргумент можно не указывать в Шаблон-идентификатор называть явное шаблон функции
специализация при условии, что это может быть выведено из типа аргумента функции.
Если вы не хотите повторять тип, вы можете использовать auto
:
template<> auto a<int> = 1;
[Живой пример] используя Clang.
С этим нужно иметь в виду одно: при использовании auto
тип специализированной переменной будет выведен из инициализатора, а не из аргумента шаблона. А поскольку специализация может иметь тип, отличный от основного шаблона, компилятор с радостью примет его, даже если они различаются.