2013-02-23 25 views
11

Clang 3.2のバグかC++ 03の違反かどうかは不明ですが、テンプレートクラスのテンプレートコンストラクタの明示的なインスタンス化は失敗しますが、テンプレート化されたテンプレートクラスのメンバ関数は成功します。例えばテンプレートクラスのテンプレートコンストラクタの明示的なインスタンス化

、と問題なく次のコンパイルの両方打ち鳴らす++およびg ++:++ 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); 

しかし++打ち鳴らすで失敗:特に

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

、I次の形式の2つのエラーメッセージを参照してください。

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

これは違反ですか標準のバグかclang ++のバグ?

+3

有効なC++ 03のように見えます。おそらくClangのバグです。++ –

答えて

5

GCCのバグを見つけたようです。これらは、両方の暗黙的に宣言されたコピーコンストラクタ名前:[temp.explicit] P4パー

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

明示的なインスタンス名の宣言暗黙的に宣言された特別なメンバ関数の場合を(第12条) 、プログラムは不正な形式です。

したがって、このコードを拒否するには正しいです。

+0

リチャードに感謝します!あなたは絶対に正しいです。明示的にコンストラクタFoo(const Foo &foo)を宣言し、コピーコンストラクタの明示的なインスタンスを削除することによって、プログラムはClangでコンパイルされます。 –

関連する問題