12 votes

Instanciation explicite d'un constructeur modèle pour une classe modèle

Je ne sais pas s'il s'agit d'un bogue dans Clang 3.2 ou d'une violation de C++03, mais il semble que l'instanciation explicite des constructeurs template pour les classes template échoue, mais que l'instanciation explicite des fonctions membres templated des classes template réussit.

Par exemple, le texte suivant se compile sans problème avec clang++ et 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 );

alors que la version suivante se compile sans avertissement avec g++ mais échoue avec 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 );

En particulier, je vois deux messages d'erreur de la forme :

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>;
               ^

S'agit-il d'une violation de la norme ou d'un bogue dans clang++ ?

6voto

Richard Smith Points 3935

Il semble que vous ayez trouvé un bogue dans GCC. Les deux nomment le constructeur copy implicitement déclaré :

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

Par [temp.explicit]p4,

Si la déclaration de l'instanciation explicite nomme une fonction membre spéciale implicitement déclarée (article 12), le programme est mal formé.

Clang a donc raison de rejeter ce code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X