【问题标题】:Explicit instantiation of templated constructor for template class模板类的模板化构造函数的显式实例化
【发布时间】:2013-02-09 08:26:31
【问题描述】:

我不确定这是 Clang 3.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 );

特别是,我看到了两条错误消息:

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++中的错误?

【问题讨论】:

  • 看起来像有效的 C++03。可能是 Clang++ 中的错误

标签: c++ clang clang++ explicit-instantiation


【解决方案1】:

您似乎发现了一个 GCC 错误。这些都命名了隐式声明的复制构造函数:

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

根据 [temp.explicit]p4,

如果显式实例化的声明命名了一个隐式声明的特殊成员函数(第 12 条),则程序是非良构的。

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

【讨论】:

  • 谢谢理查德!你是绝对正确的。通过显式声明构造函数 Foo( const Foo& foo ) 并删除复制构造函数的显式实例化,然后程序使用 Clang 编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多