我是一个简单的程序员.我的类成员变量通常由POD类型和STL容器组成.因此,我很少需要编写赋值运算符或复制构造函数,因为这些是默认实现的.
除此之外,如果我使用std::move不可移动的对象,它使用赋值运算符,这意味着std::move非常安全.
由于我是一个简单的程序员,我想利用移动功能,而不需要为我编写的每个类添加移动构造函数/赋值运算符,因为编译器可以简单地将它们实现为" this->member1_ = std::move(other.member1_);..."
但它没有(至少在Visual 2010中没有),有什么特别的原因吗?
更重要的是; 有没有办法解决这个问题?
更新: 如果你低头看GManNickG的答案,他会为此提供一个很棒的宏.如果你不知道,如果你实现了移动语义,你可以删除交换成员函数.
因此,在查找移动语义之后,我发现当您打算转移所有权时,普遍的共识是通过值传递.但在Scott Meyer关于Universal引用的讨论中,我注意到std::vector::push_back有2个重载:
void push_back( const T& value );
void push_back( T&& value );
Run Code Online (Sandbox Code Playgroud)
所以我心想,void push_back( T value );不够吗?我问了一些最终导致以下测试用例的人:
#include <memory>
#include <iostream>
#include <type_traits>
struct A
{
A() { std::cout << "A Default constructor\n"; }
A(const A &) { std::cout << "A Copy\n"; }
A(A &&) { std::cout << "A Move\n"; }
};
std::aligned_storage<sizeof(A)> contents;
A& alias = *reinterpret_cast<A*>(&contents);
void ByVal(A a)
{
new (&contents) A(std::move(a));
alias.~A();
}
void ByLCRef(A const& a)
{
new …Run Code Online (Sandbox Code Playgroud) 根据N3485§23.3.2.2:
(...)数组的隐式移动构造函数和移动赋值运算符要求T 分别为MoveConstructible或MoveAssignable.
因此,std::array如果元素的类型支持,则支持移动语义.大!
但是,这究竟意味着什么?我倾向于将这种类型描述为提供符合STL标准的接口的更安全的数组版本,但是,如果这是真的,那么std::array移动构造它的元素怎么样?我可以用普通数组做同样的事情吗?
我在visual studio 11上尝试了一些新的C++ 11功能,从移动构造函数开始.我写了一个名为"MyClass"的简单类,其中包含一个移动构造函数:
class MyClass
{
public:
explicit MyClass( int aiCount )
: mpiSize( new int( aiCount ) ),
miSize2( aiCount)
{
}
MyClass( MyClass&& rcOther )
: mpiSize( rcOther.mpiSize )
, miSize( *rcOther.mpiSize )
{
rcOther.mpiSize = 0;
rcOther.miSize = 0;
}
~MyClass()
{
delete mpiSize;
}
private:
int *mpiSize;
int miSize2;
};
Run Code Online (Sandbox Code Playgroud)
我在这里有问题:
为什么push_back以下的功能签名?
void push_back (const value_type& val);
Run Code Online (Sandbox Code Playgroud)
传递的值被复制到容器中,为什么不将副本直接复制到参数列表中?
void push_back (value_type val);
Run Code Online (Sandbox Code Playgroud)