Подтвердить что ты не робот

Предупреждение С++ 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?
}

В чем тайна этого синтаксиса?

4b9b3361

Ответ 1

Аргументы шаблона могут быть опущены только при явной специализации шаблонов функций. У вас есть шаблон переменной, поэтому вы должны включить <int>:

template<> int a<int> = 1;

Цитата С++ 14 (n4140), 14.7.3/10 (внимание мое):

Возвращаемый шаблон-аргумент может быть оставлен неуказанным в идентификаторе шаблона, именовав явный шаблон функции специализация, если она может быть выведена из типа аргумента функции.

Если вы не хотите повторять тип, вы можете использовать auto:

template<> auto a<int> = 1;

[Живой пример], используя Clang.

Здесь следует иметь в виду следующее: при использовании auto тип специализированной переменной будет выведен из инициализатора, а не из аргумента шаблона. И поскольку специализация может иметь другой тип, чем основной шаблон, компилятор с радостью примет его, даже если он отличается.