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

Sam*_*rsa 6 c++ templates default-constructor

我问过这个问题,关于使用模板版本重载复制构造函数和赋值运算符并考虑到涉及问题的混淆(因为它似乎是编译器错误),我想我只尝试使用模板复制构造函数和模板赋值运算符来走着瞧吧.但是编译器完全忽略了它们.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Naw*_*waz 8

template<typename T>
BaseClass(const T& a_other) 
Run Code Online (Sandbox Code Playgroud)

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

复制构造函数应该是这样的:

BaseClass(const BaseClass & a_other)
Run Code Online (Sandbox Code Playgroud)

请注意区别?

请注意,模板化构造函数不定义复制构造函数.编译器将仍然产生一个默认的拷贝构造函数为你,而不是实例化的模板构造函数.

复制赋值的参数相同.


Mic*_*urr 5

如您对其他问题的回答中所述,该标准明确禁止使用该标准。

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

有些人可能认为这已经是这些函数的“通用”隐式版本了,这真是太糟糕了,它对许多类默默地做错了事。

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

从C ++ 03 12.8“复制类对象”开始

  • (段落1):A 类X的非模板构造函数的第一个参数为X&,const X&,volatile X&或const volatile X&类型,并且没有其他参数,或者所有其他参数都具有默认值,则它是副本构造函数论点(8.3.6)
  • (第9段):用户声明的副本分配运算符X :: operator =是X类的非静态非模板成员函数,具有恰好一个参数,类型为X,X&,const X&,volatile X&或const volatile X&