我是一个简单的程序员.我的类成员变量通常由POD类型和STL容器组成.因此,我很少需要编写赋值运算符或复制构造函数,因为这些是默认实现的.
除此之外,如果我使用std::move不可移动的对象,它使用赋值运算符,这意味着std::move非常安全.
由于我是一个简单的程序员,我想利用移动功能,而不需要为我编写的每个类添加移动构造函数/赋值运算符,因为编译器可以简单地将它们实现为" this->member1_ = std::move(other.member1_);..."
但它没有(至少在Visual 2010中没有),有什么特别的原因吗?
更重要的是; 有没有办法解决这个问题?
更新: 如果你低头看GManNickG的答案,他会为此提供一个很棒的宏.如果你不知道,如果你实现了移动语义,你可以删除交换成员函数.
我有一个std::vector特定类的对象A.该类非常重要,并且定义了复制构造函数和移动构造函数.
std::vector<A> myvec;
Run Code Online (Sandbox Code Playgroud)
如果我用A对象填充向量(使用例如myvec.push_back(a)),则向量将增大,使用复制构造函数A( const A&)来实例化向量中元素的新副本.
我可以以某种方式强制执行类的移动构造函数A而不是使用它吗?
重用移动容器的正确方法是什么?
std::vector<int> container;
container.push_back(1);
auto container2 = std::move(container);
// ver1: Do nothing
//container2.clear(); // ver2: "Reset"
container = std::vector<int>() // ver3: Reinitialize
container.push_back(2);
assert(container.size() == 1 && container.front() == 2);
Run Code Online (Sandbox Code Playgroud)
从我在C++ 0x标准草案中读到的内容; ver3似乎是正确的方法,因为移动后的对象在a中
"除非另有规定,否则此类移动物体应处于有效但未指明的状态."
我从来没有找到任何"以其他方式指定"的实例.
虽然我发现ver3有点回旋并且会有更多首选ver1,虽然vec3可以允许一些额外的优化,但另一方面很容易导致错误.
我的假设是否正确?
在C++中,11 emplace_back()通常是优选的(在效率方面),push_back()因为它允许就地构造,但是当使用push_back(std::move())已经构造的对象时仍然是这种情况吗?
例如,emplace_back()在以下情况下仍然是首选?
std::string mystring("hello world");
std::vector<std::string> myvector;
myvector.emplace_back(mystring);
myvector.push_back(std::move(mystring));
// (of course assuming we don't care about using the value of mystring after)
Run Code Online (Sandbox Code Playgroud)
另外,在上面的例子中有没有任何好处来代替:
myvector.emplace_back(std::move(mystring));
Run Code Online (Sandbox Code Playgroud)
或者这里的举动完全是多余的,还是没有效果?
函数应该返回RValue Reference是否有原因?技巧,技巧,或成语或模式?
MyClass&& func( ... );
Run Code Online (Sandbox Code Playgroud)
我知道一般返回引用的危险,但有时我们会这样做,不管我们(T& T::operator=(T)只是一个惯用的例子).但是怎么样T&& func(...)?我们会从中获得这样的一般场所吗?与仅仅客户端代码相比,当编写库或API代码时,可能会有所不同?
如果std::string支持移动语义,我应该通过值传递还是通过引用传递(到非内联函数)?那么使用小字符串优化(SSO)的实现呢?
为unique_ptr保证存储nullptr移动之后?
std::unique_ptr<int> p1{new int{23}};
std::unique_ptr<int> p2{std::move(p1)};
assert(!p1); // is this always true?
Run Code Online (Sandbox Code Playgroud) 我有一个围绕可移动对象的代理容器类,并希望代理能够隐式地产生对底层对象的rvalue引用,但仅在代理本身被移动时.
我相信我将能够按照提议n2439 "将移动语义扩展到*this"来实现此行为,但它尚未在gcc的发行版中提供,并且暂时不会出现.
下面的代码是我最终的目标,但目前无法实现.在此功能可用之前,是否有任何等效的解决方法?
template< class T >
struct movable_proxy {
operator T&&() && {
return std::move(value);
}
operator const T&() const& {
return value;
}
private:
T value;
};
Run Code Online (Sandbox Code Playgroud) 在重新分配时,在确定是否移动或复制元素之前,向量将检查移动构造函数是否标记为noexcept.默认移动构造函数是否定义为noexcept?我看到了以下文档,但没有说明这一点.http://en.cppreference.com/w/cpp/language/move_constructor
隐式声明的移动构造函数
如果没有为类类型(结构,类或联合)提供用户定义的移动构造函数,并且满足以下所有条件:没有用户声明的复制构造函数没有用户声明的复制赋值运算符没有用户声明的移动赋值运算符没有用户声明的析构函数,由于下一节中详述的条件,隐式声明的移动构造函数未定义为已删除,因此编译器将声明移动构造函数作为其类的内联公共成员signature T :: T(T &&)一个类可以有多个移动构造函数,例如T :: T(const T &&)和T :: T(T &&).如果存在一些用户定义的移动构造函数,则用户仍可以使用关键字default强制生成隐式声明的移动构造函数.
我一直在观看Scott Meyers 关于 C++和2012 年之后的Universal References的演讲,到目前为止一切都很有意义.然而,一位观众在大约50分钟后问了一个问题,我也在想.迈尔斯说,他不关心答案,因为它不是惯用的,会愚蠢的想法,但我仍然感兴趣.
提供的代码如下:
// Typical function bodies with overloading:
void doWork(const Widget& param) // copy
{
// ops and exprs using param
}
void doWork(Widget&& param) // move
{
// ops and exprs using std::move(param)
}
// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param) // forward => copy and move
{
// ops and exprs using std::forward<T>(param)
}
Run Code Online (Sandbox Code Playgroud)
关键是当我们采用右值引用时,我们知道我们有一个右值,所以我们应该std::move保留它是一个右值的事实.当我们采用通用引用(T&&其中T是推导类型)时,我们希望std::forward保留它可能是左值或右值的事实.
所以问题是:既然 …
c++ rvalue-reference move-semantics perfect-forwarding c++11
move-semantics ×10
c++ ×9
c++11 ×9
constructor ×1
emplace ×1
pod ×1
push-back ×1
resize ×1
std ×1
string ×1
unique-ptr ×1
vector ×1