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

Why can't I override the default copy constructor and assignment operator with template versions in C++

本文关键字:默认 覆盖 版本 复制 赋值运算符 构造函数 不能 C++ 为什么      更新时间:2023-10-16

我问了这个关于用模板版本重载复制构造函数和赋值运算符的问题,并考虑到围绕这个问题的混乱(因为这似乎是一个编译器错误),我想我应该只使用模板复制构造函数和模板赋值运算符来看看会发生什么。但是编译器完全忽略了它们。

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

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

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

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

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

BaseClass(const BaseClass & a_other)

注意到区别了吗?

请注意,模板化构造函数没有定义复制构造函数。编译器仍将为您生成默认的复制构造函数,而不是实例化模板化的构造函数。

副本分配的参数相同。

正如在回答您的另一个问题时所提到的,标准明确禁止它。

我想,一个基本原理是,如果这些构造函数的非默认值是必要的,那是因为它们需要处理有问题的类的细节。"通用"解决方案没有意义,可能会悄悄地隐藏潜在的问题。

有些人可能认为,这些函数已经有了"泛型"隐式版本,这已经够糟糕的了,它对许多类默默地做了错误的事情。

标准的不允许模板versino在这里:

从C++03 12.8"复制类对象"

  • (第1段):类X的非模板构造函数是复制构造函数,如果它的第一个参数是类型X&,常量X&,易失性X&或常数易失性X&,并且要么没有其他参数,要么所有其他参数都有默认参数(8.3.6)
  • (第9段):用户声明的复制赋值运算符X::operator=是类X的非静态非模板成员函数,仅具有一个类型为X、X&的参数;,常量X&,易失性X&或常量易失性X&