且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

模板类的模板化构造函数的显式实例化

更新时间:2022-10-24 14:54:17

看起来您发现了一个GCC错误。这两个名称都是隐含声明的复制构造函数:

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

每个[temp.explicit] p4,




如果显式实例化的声明命名一个隐含声明的特殊成员函数(第12条),程序就会生成错误。


因此,Clang拒绝此代码是正确的。


I am uncertain if it is a bug in Clang 3.2 or a violation of C++03, but it appears that explicit instantiation of templated constructors for template classes fails, but explicit instantiation of templated member functions of template classes succeeds.

For instance, the following compiles without a problem with both clang++ and 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 );

whereas the following compiles without warning with g++ but fails with 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 particular, I see two error messages of the form:

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

Is this a violation of the standard or a bug in clang++?

It looks like you've found a GCC bug. These both name the implicitly-declared copy constructor:

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

Per [temp.explicit]p4,

If the declaration of the explicit instantiation names an implicitly-declared special member function (Clause 12), the program is ill-formed.

Therefore Clang is correct to reject this code.