模板类跨类型复制构造函数是否需遵循五五法则?该构造函数是否为复制构造函数?
1. 该类是否需要遵循五五法则?
先明确一下什么是五五法则(Rule of Five):当你显式定义了析构函数、复制构造函数、复制赋值运算符、移动构造函数、移动赋值运算符中的任意一个时,就应该考虑显式定义(或用default/delete声明)所有这五个特殊成员函数,避免编译器自动生成的版本不符合你的预期。
回到你的类A<T>:你只定义了两个构造函数——一个接受const T&的普通构造函数,一个模板构造函数用于从A<M>转换到A<T>。你没有显式声明任何属于五五法则范畴的特殊成员函数,所以编译器会自动为A<T>生成默认的版本:
- 默认析构函数:调用
T的析构函数销毁m_value - 默认复制构造函数:复制传入对象的
m_value到当前对象 - 默认复制赋值运算符:赋值传入对象的
m_value到当前对象 - 默认移动构造函数:移动传入对象的
m_value到当前对象 - 默认移动赋值运算符:移动传入对象的
m_value到当前对象
这些默认生成的版本完全适配你的类——因为A<T>只是简单封装了一个T类型成员,没有手动管理动态内存、文件句柄这类需要自定义生命周期的资源。所以你的类不需要遵循五五法则,除非你有特殊需求(比如禁止移动操作、自定义复制逻辑),否则直接用编译器生成的版本就足够了。
2. template <typename T>template <typename M> A<T>::A(const A<M>& other) 是否不属于复制构造函数?
没错,它不属于复制构造函数。
根据C++标准,类X的复制构造函数必须满足:第一个参数是X&、const X&、volatile X&或const volatile X&,且其他参数(如果有)都带有默认值。
而你的模板构造函数参数是const A<M>&,这里的M可以是和T不同的类型——比如当T=int、M=double时,这个构造函数的作用是把A<double>转换为A<int>,本质是一个模板转换构造函数,而非复制构造函数。
另外还有个关键点:这个模板构造函数不会覆盖编译器生成的默认复制构造函数。比如当你用A<int>对象初始化另一个A<int>对象时,编译器会调用它自动生成的默认复制构造函数,而不是这个模板构造函数——哪怕M=T时参数类型匹配,模板构造函数也不会被视为复制构造函数,编译器仍然会生成默认版本。
内容的提问来源于stack exchange,提问作者apalomer

