为什么我不能用C ++中的模板版本覆盖默认的复制构造函数和赋值运算符

时间:2012-02-28 18:45:45

标签: c++ templates default-constructor

我问this question有关使用模板版本重载复制构造函数和赋值运算符并考虑到涉及问题的混淆(因为它似乎是一个编译器错误),我想我只尝试使用模板复制构造函数和模板赋值运算符,看看会发生什么。但是编译器完全忽略了它们。

struct BaseClass
{
public:
  BaseClass() {}

  template<typename T>
  BaseClass(const T& a_other)
  {
    int i = 0; // for break point which is not hit
  }

  template<typename T>
  BaseClass& operator= (const T& a_other)
  {
    int i = 0; // for break point which is not hit
    return *this;
  }

};

struct MyClass : public BaseClass
{
};

int main()
{
  MyClass i, j;
  i = j;

  return 0;
}

为什么我不能用模板版本覆盖默认值(我怀疑答案是默认值是更好的匹配但我希望模板版本作为默认值作为默认值好)?我能做些什么来确保调用模板版本而不是默认值?

2 个答案:

答案 0 :(得分:7)

template<typename T>
BaseClass(const T& a_other) 

首先,这不是复制构造函数。它是一个模板构造函数。

复制构造函数应为:

BaseClass(const BaseClass & a_other)

注意区别?

请注意,模板化构造函数未定义复制构造函数。编译器为您生成一个默认的拷贝构造函数,而不是实例化模板化的构造函数。

复制分配的相同参数。

答案 1 :(得分:4)

正如您在回答其他问题时所提到的那样,该标准明确禁止它。

我猜测的理由是,如果这些构造函数的非默认值是必要的,那将是因为它们需要处理所讨论的类的细节。 “通用”解决方案没有意义,可能会悄悄隐藏潜在问题。

有些人可能认为已经存在这些函数的“通用”隐式版本已经足够糟糕了,这些函数默默地为许多类做错了。

这些禁止模板的标准版本在这里:

From C ++ 03 12.8“复制类对象”

  • (第1段):类X的非模板构造函数是复制构造函数,如果它的第一个参数是X&amp;类型,const X&amp;,volatile X&amp;或const volatile X&amp;,并且没有其他参数或者所有其他参数都有默认参数(8.3.6)
  • (第9段):用户声明的复制赋值运算符X :: operator =是X类的非静态非模板成员函数,其中只有一个类型为X,X&amp;的参数。 ,const X&amp;,volatile X&amp;或const volatile X&amp;