Специализация шаблонной функции после точки использования нарушит компиляцию - PullRequest
5 голосов
/ 06 мая 2011

Рассмотрим следующий пример:

#include <iostream>

template< int a >
void foo();

int main(int argn, char* argv[])
{
    foo<1>();
}

template<>
void foo<1>()
{
    std::cout<<1<<std::endl;
}

Компиляция завершается неудачно со следующими сообщениями об ошибках:

rg.cpp:12: error: specialization of ‘void foo() [with int a = 1]’ after instantiation

Какой параграф в стандарте объясняет эту ошибку?

PSЯ знаю, что если я переместу определение функции перед основным, ошибка исчезнет.

1 Ответ

10 голосов
/ 06 мая 2011

Я думаю, что это неопределенное поведение в соответствии со стандартом. Нет никаких ограничений на то, что может делать цепочка инструментов в случаях UB, генерирование ошибки компилятора является одной из более дружественных возможностей.


Раздел [temp.spec], 14.7p5 говорит

Для данного шаблона и заданного набора аргументов шаблона ,

  • явное определение экземпляра должно появляться в программе не более одного раза,
  • явная специализация должна быть определена не более одного раза в программе (согласно 3.2), а
  • и явная реализация, и декларация явной специализации не должны появляться в программа, если явная реализация не следует объявлению явной специализации.

Реализация не требуется для диагностики нарушения этого правила.

Раздел [temp.expl.spec] 14.7.3p6 говорит:

Если шаблон, шаблон элемента или член шаблона класса явно специализированы, то эта специализация должна быть объявлена ​​до первого использования этой специализации, которая вызовет неявную реализацию каждая единица перевода, в которой происходит такое использование; Диагностика не требуется.


Ваша программа нарушает эти требования.

...