C++ 从模板类继承时如何应用移动语义
当我运行下面的代码时,它会生成以下输出, 第一部分直接使用模板, 第二种方法使用从模板派生的类。 在派生类中不调用移动语义(以粗体显示) 模板虚拟:正在初始化构造函数C++ 从模板类继承时如何应用移动语义,c++,c++11,templates,move-semantics,C++,C++11,Templates,Move Semantics,当我运行下面的代码时,它会生成以下输出, 第一部分直接使用模板, 第二种方法使用从模板派生的类。 在派生类中不调用移动语义(以粗体显示) 模板虚拟:正在初始化构造函数 模板虚拟:正在初始化构造函数 模板伪:空构造函数 模板伪:空构造函数 模板虚拟:+运算符 模板虚拟:移动分配 2 模板虚拟:正在初始化构造函数 模板虚拟:正在初始化构造函数 模板伪:空构造函数 模板伪:空构造函数 模板虚拟:+运算符 模板伪:复制构造函数 模板虚拟:复制分配 2 我认为,原因很清楚——命名参数会将参数转换为左值,因
模板虚拟:正在初始化构造函数
模板伪:空构造函数
模板伪:空构造函数
模板虚拟:+运算符
模板虚拟:移动分配
2
模板虚拟:正在初始化构造函数
模板虚拟:正在初始化构造函数
模板伪:空构造函数
模板伪:空构造函数
模板虚拟:+运算符
模板伪:复制构造函数
模板虚拟:复制分配
2
我认为,原因很清楚——命名参数会将参数转换为左值,因此模板接收左值并调用副本构造函数 问题是在这种情况下如何强制移动语义
#include <iostream>
using namespace std;
template <typename T> class Dummy {
public:
T val;
Dummy& operator=(const Dummy& d){
val = d.val;
cout << "Template Dummy: copy assignment\n" ;
return *this;
}
Dummy operator+(const Dummy &d) {
Dummy res;
res.val = val + d.val;
cout << "Template Dummy: + operator\n" ;
return res;
}
// constructors
Dummy() {
val = 0;
cout << "Template Dummy: empty constructor\n" ;
}
Dummy(const T v) {
val = v;
cout << "Template Dummy: initializing constructor\n" ;
}
Dummy(const Dummy &d) {
val = d.val;
cout << "Template Dummy: copy constructor\n" ;
}
// move semantics
Dummy(const Dummy&& d) {
val = d.val;
cout << "Template Dummy: move constructor\n" ;
}
Dummy& operator=(const Dummy&& d){
val = d.val;
cout << "Template Dummy: move assignment\n" ;
return *this;
}
};
class FloatDummy : public Dummy<float> {
public:
FloatDummy& operator=(const FloatDummy& d){
Dummy<float>::operator=(d);
return *this;
}
FloatDummy operator+(const FloatDummy &d) {
return (FloatDummy) Dummy<float>::operator+(d);
}
// constructors
FloatDummy() : Dummy<float>() {};
FloatDummy(float v) : Dummy<float>(v) {}
FloatDummy(const FloatDummy &d) : Dummy<float>(d) {}
FloatDummy(const Dummy<float> &d) : Dummy<float>(d) {}
// move semantics
FloatDummy(const FloatDummy&& d) : Dummy<float>(d) {}
FloatDummy& operator=(const FloatDummy&& d){
// here d is already an lvalue because it was named
// thus the template invokes a copy assignment
Dummy<float>::operator=(d);
return *this;
}
};
int main() {
Dummy<float> a(1), b(1);
Dummy<float> c;
c = a + b;
cout << c.val << '\n';;
FloatDummy d(1), e(1);
FloatDummy f;
f = d + e;
cout << f.val << '\n';
}
#包括
使用名称空间std;
模板类虚拟{
公众:
T值;
虚拟和运算符=(常量虚拟和d){
val=d.val;
cout您不能从常量移动&
。要修复此问题,只需从所有移动操作中删除常量
:
FloatDummy(FloatDummy&& d) : Dummy<float>(d) {}
// ^^^^^^^^^^^^ no longer FloatDummy const&&
FloatDummy& operator=(FloatDummy&& d) { /*...*/ }
// ^^^^^^^^^^^^ ditto
从const&
的所有案例中删除const
,并使用std::move(d)
从d
移动。这解决了问题。我还有一个缺少的移动构造函数,它不是从模板复制的,导致了复制。现在我有一个移动构造函数和一个移动分配。谢谢!!
FloatDummy(FloatDummy&& d) : Dummy<float>(std::move(d)) {}
// ^^^^^^^^^ calling std::move()
// otherwise copy ctor overload is chosen
FloatDummy& operator=(FloatDummy&& d)
{
Dummy<float>::operator=(std::move(d));
// ^^^^^^^^^ ditto
return *this;
}