Наступне:
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
дасть різні результати), програма неправильно формується НДР.