Dato il seguente modello di classe:
template<typename T>
struct Outer
{
struct Inner;
auto f(Inner) -> void;
};
definiamo Inner
separatamente per ogni specializzazione di Outer
:
template<>
struct Outer<int>::Inner {};
template<>
struct Outer<double>::Inner {};
e quindi definire f
una volta la funzione membro per tutte le specializzazioni di Outer
:
auto Outer<T>::f(Inner) -> void
{
}
ma Clang (9.0.0) si lamenta:
error: variable has incomplete type 'Outer::Inner'
auto Outer<T>::f(Inner) -> void
^
Possiamo eludere l'errore del compilatore fornendo anche una definizione di Inner
per tutte le altre specializzazioni di Outer
:
template<typename T>
struct Outer<T>::Inner {};
o definendo f
separatamente per ogni specializzazione:
template<>
auto Outer<int>::f(Inner) -> void
{
}
template<>
auto Outer<double>::f(Inner) -> void
{
}
Sia GCC che MSVC accettano il codice iniziale, che pone la domanda; si tratta di un bug di Clang o è l'unica implementazione conforme delle tre?
Inner
per tutte le altre specializzazioni sia la definizione f
separata per ciascuna specializzazione risolvono l'errore di compilazione.
Inner
veniva segnalato come un tipo incompleto nonostante le definizioni per ogni specializzazione di Outer
essere fornita. Chiaramente Inner
sarà (correttamente) un tipo incompleto se si rimuovono le sue definizioni.