Pet*_*rNL 2 c++ move perfect-forwarding c++11 c++14
我已经测试了C++ 11中的Semantic移动.我用移动构造函数编写了一个类.
class DefaultConstructor
{
public:
DefaultConstructor(std::vector<int> test) :
m_vec(std::forward<std::vector<int>>(test))
{
};
DefaultConstructor(DefaultConstructor &&def) :
m_vec(std::forward<std::vector<int>>(def.m_vec))
{
}
DefaultConstructor& operator=(DefaultConstructor&& def) {
m_vec = std::move(def.m_vec);
return *this;
}
DefaultConstructor& operator=(const DefaultConstructor&) = delete;
DefaultConstructor(DefaultConstructor &) = delete;
std::vector<int> m_vec;
};
Run Code Online (Sandbox Code Playgroud)
我写了一个使用移动语义的主函数.我理解移动语义中发生的事情,它是很棒的工具.但是有些行为对我来说是不可解释的.当我打电话DefaultConstructor testConstructor2 = std::move(testConstructor);给我的主要功能DefaultConstructor& operator=(DefaultConstructor&& def)应该叫.但Visual Studio 2015调用了移动构造函数.
int main()
{
std::vector<int> test = { 1, 2, 3, 4, 5 };
DefaultConstructor testConstructor(std::move(test));
DefaultConstructor testConstructor2 = std::move(testConstructor);
DefaultConstructor &testConstructor3 = DefaultConstructor({ 6, 7, 8, 9 });
DefaultConstructor testConstructor4 = std::move(testConstructor3);
swapMove(testConstructor, testConstructor2);
}
Run Code Online (Sandbox Code Playgroud)
好吧,我想也许不再需要= Move Operator了.但我尝试了一个SwapMove功能.此函数调用= move运算符.
template<typename T>
void swapMove(T &a, T &b)
{
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释这两个电话的区别究竟是什么?不应该是电话a = std::move(b);并且DefaultConstructor testConstructor2 = std::move(testConstructor);具有相同的行为?
语法
DefaultConstructor testConstructor2 = something;
Run Code Online (Sandbox Code Playgroud)
总是调用构造函数,因为该对象testConstructor2尚不存在.operator =只能在已构造的对象的上下文中调用.
这个:
T foo = bar;
Run Code Online (Sandbox Code Playgroud)
称为复制初始化.它通常(但不总是)等同于:
T foo(bar);
Run Code Online (Sandbox Code Playgroud)
不同的是,后者是一个直接函数调用T的构造,而前者中尝试从构造的隐式转换序列decltype(bar)到T.因此,存在直接初始化成功但复制初始化可能失败的情况.无论哪种方式,初始化都是初始化:它是构造函数调用,而不是赋值调用.
在我们的例子中,这两行完全相同:
DefaultConstructor testConstructor2 = std::move(testConstructor);
DefaultConstructor testConstructor2{std::move(testConstructor)};
Run Code Online (Sandbox Code Playgroud)
他们都没有打来电话DefaultConstructor::operator=.