2013-02-23 9 views
11

Non sono sicuro se si tratta di un bug in Clang 3.2 o di una violazione di C++ 03, ma sembra che l'istanziazione esplicita di costruttori basati su modelli per le classi modello non riesca, ma l'istanziazione esplicita di modelli le funzioni membro delle classi template hanno successo.Istanza esplicita del costruttore con modello per la classe modello

Ad esempio, i seguenti compila senza problemi sia con clangore ++ e g ++:

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    void Bar(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template void Foo<int>::Bar(const Foo<int>& foo); 
template void Foo<int>::Bar(const Foo<float>& foo); 
template void Foo<float>::Bar(const Foo<int>& foo); 
template void Foo<float>::Bar(const Foo<float>& foo); 

che i seguenti compilazioni senza avvertimento con g ++ ma non riesce con clang ++:

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    Foo(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<int>::Foo(const Foo<float>& foo); 
template Foo<float>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

In particolare, vedere due messaggi di errore del modulo:

TemplateMember.cpp:12:20: error: explicit instantiation refers to member 
     function 'Foo<int>::Foo' that is not an instantiation 
template Foo<int>::Foo(const Foo<int>& foo); 
       ^
TemplateMember.cpp:9:16: note: explicit instantiation refers here 
template class Foo<int>; 
      ^

È una violazione dello standard o un bug in clang ++?

+3

Sembra C++ 03 valido. Probabilmente bug in Clang ++ –

risposta

5

Sembra che tu abbia trovato un bug GCC. Questi nome sia il costruttore di copia implicitamente dichiarata:

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

Per [temp.explicit] p4,

Se la dichiarazione dei nomi esplicita di istanza di una funzione di membro speciale implicitamente dichiarata (Clausola 12) , il programma è mal formato.

Pertanto Clang è corretto per rifiutare questo codice.

+0

Grazie, Richard! Hai assolutamente ragione. Dichiarando esplicitamente il costruttore Foo (const Foo & foo) e rimuovendo le istanze esplicite del costruttore di copie, il programma viene compilato con Clang. –

Problemi correlati