/ / Явна інстанціяція шаблону функції з використанням неповного типу - c ++, шаблонів

Явна демонстрація шаблону функції з використанням неповного типу - c + +, шаблонів

Наступне:

template< typename >
struct S;

template< typename T >
S< T >& f (S< T >& s) {
const typename S< T >::nested ignore;
return s;
}

template S< char >& f (S< char >&);

template< typename >
struct S {
struct nested { };
};

компілює з gcc, але не з clang:

$ clang -c /tmp/t.cpp
/tmp/t.cpp:6:20: error: implicit instantiation of undefined template "S<char>"
const typename S< T >::nested ignore;
^
/tmp/t.cpp:10:21: note: in instantiation of function template specialization "f<char>" requested here
template S< char >& f (S< char >&);
^
/tmp/t.cpp:2:8: note: template is declared here
struct S;
^
1 error generated.

Я вважаю, що Кланг має рацію в цьому, в точціІнстанціювання, функція f посилається на неповне визначення S. OTOH, пізніша спеціалізація S може дати правильне визначення, яке робить залежне "вкладене" добре сформованим. Будь-які думки?

Відповіді:

2 для відповіді № 1

Обидва компілятори є правильними.

[temp.point] / p6, 8:

6 Явне визначення екземпляра є моментом для спеціалізація або спеціалізація, визначена явним обґрунтування

8 Спеціалізація для шаблону функцій [...] може мати кілька точок примірників всередині перекладацької одиниці та крім вищеописаних моментів опису для будь-яких така спеціалізація, яка має точку інстанції в межах Одиниця перекладу, кінець одиниці перекладу також вважається a точка моменту. [...] Якщо дві різні точки інстанції надати спеціалізації шаблону різні значення відповідно до одного правило визначення (3.2), програма неправильно сформована, діагностики немає вимагається.

Є два моменти для f<char>: за чітким визначенням інстанції та в кінці ТУ. Тому що ці два пункти примірника можуть спричинити різні значення (як пошук S<T>::nested дасть різні результати), програма неправильно формується НДР.