当派生函数定义了析构函数时,使用复制函数而不是移动函数
Using copy ctor instead of move ctor when derived has destructor defined
当我向派生类添加析构函数时,当它试图使用复制函数而不是定义的移动函数时,我得到编译器错误(使用gcc 4.7):
#include <utility>
#include <iostream>
template <typename T>
struct Base
{
T value;
Base(T&& value) :
value(value)
{
std::cout << "base ctor" << std::endl;
}
Base& operator=(const Base&) = delete;
Base(const Base&) = delete;
Base& operator=(Base&& rhs)
{
value = rhs.value;
std::cout << "move assignment" << std::endl;
}
Base(Base&& other) :
value(other.value)
{
std::cout << "move ctor" << std::endl;
}
virtual ~Base()
{
std::cout << "base dtor" << std::endl;
}
};
template <typename T>
struct Derived : public Base<T>
{
Derived(T&& value) :
Base<T>(std::forward<T>(value))
{
std::cout << "derived ctor" << std::endl;
}
~Derived()
{
std::cout << "derived dtor" << std::endl;
}
};
template <typename T>
Derived<T> MakeDerived(T&& value)
{
return Derived<T>(std::forward<T>(value));
}
struct Dummy {};
int main()
{
auto test = MakeDerived(Dummy());
}
此代码在gcc-4.5和gcc-4.6上可以很好地编译。来自gcc-4.7的错误如下:
test.cpp: In function ‘int main()’:
test.cpp:61:34: error: use of deleted function ‘Derived<Dummy>::Derived(const Derived<Dummy>&)’
test.cpp:37:8: note: ‘Derived<Dummy>::Derived(const Derived<Dummy>&)’ is implicitly deleted because the default definition would be ill-formed:
test.cpp:37:8: error: use of deleted function ‘Base<T>::Base(const Base<T>&) [with T = Dummy; Base<T> = Base<Dummy>]’
test.cpp:16:3: error: declared here
test.cpp: In instantiation of ‘Derived<T> MakeDerived(T&&) [with T = Dummy]’:
test.cpp:61:34: required from here
test.cpp:54:43: error: use of deleted function ‘Derived<Dummy>::Derived(const Derived<Dummy>&)’
我在这里错过了什么,或者这也应该在gcc 4.7上编译好吗?当我注释掉派生类的析构函数时,一切都好了。
gcc version 4.5.3 (Ubuntu/Linaro 4.5.3-12ubuntu2)
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-11precise2)
错误是正确的;Move构造函数仅在类没有用户定义析构函数时隐式生成。如果添加析构函数,则会抑制默认的move-构造函数,并尝试复制构造函数。当一个类具有不可复制的基类时,默认复制构造函数的生成将被禁止,因此Derived
既不可复制也不可移动。
解决方案是简单地添加一个移动构造函数到Derived
。
相关文章:
- 使用 memcpy 函数C++复制字符数组
- 使用复制构造函数复制双精度数组
- VB.NET DLL中的C++DLL函数复制
- 使用SSE内部函数复制少量数据时出现问题
- 不可变的 lambda 函数:复制捕获的变量是否允许是 const
- C 无可行的构造函数复制类型的变量
- 没有可行的构造函数复制类型 'MyString' 的数组元素
- 编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别
- 将具有默认参数的lambda函数复制到变量
- 如何最小化调用列表构造函数(复制构造函数)的次数?
- C 11矢量构造函数复制与范围
- std::函数复制运算符 (MSVC2012) 的奇怪行为
- 从函数复制成本返回STL向量
- 我定义了一个非复制构造函数;复制构造函数还会被隐式定义吗
- 可以将构造函数复制为转换运算符
- 标准::函数复制参数
- C++:strcpy 函数复制空值
- 将基类指针的构造函数复制到子类
- Zlib解压缩函数复制而不是解压缩
- C++树类:构造函数/复制/内存泄漏