12

Clang3.2のバグなのかC++03の違反なのかはわかりませんが、テンプレートクラスのテンプレートコンストラクターの明示的なインスタンス化は失敗するようですが、テンプレートクラスのテンプレート化されたメンバー関数の明示的なインスタンス化は成功します。

たとえば、以下はclang++と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 );

一方、以下はg ++では警告なしにコンパイルされますが、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 );

特に、次の形式の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 ++のバグですか?

4

1 に答える 1

6

GCC のバグを発見したようです。これらは両方とも、暗黙的に宣言されたコピー コンストラクターに名前を付けます。

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

[temp.explicit]p4あたり、

明示的なインスタンス化の宣言が、暗黙的に宣言された特別なメンバー関数 (第 12 節) を指定している場合、プログラムは形式が正しくありません。

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

于 2013-02-25T21:44:34.303 に答える