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