6

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

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

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

4

2 回答 2

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

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

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

BaseClass(const BaseClass & a_other)

注意到区别了吗?

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

复制分配的参数相同。

于 2012-02-28T18:49:50.883 回答
5

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

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

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

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

来自 C++03 12.8“复制类对象”

  • (第 1 段):如果类 X 的第一个参数的类型为 X&、const X&、volatile X& 或 const volatile X&,并且没有其他参数或所有其他参数都具有默认值,则类 X的非模板构造函数是复制构造函数论据 (8.3.6)
  • (第 9 段):用户声明的复制赋值运算符 X::operator= 是 X 类的非静态非模板成员函数,只有一个 X、X&、const X&、volatile X& 或 const volatile X& 类型的参数
于 2012-02-28T18:50:28.340 回答