下面的snipplet是否正确用于取消定义所有其他方法和类的构造函数?
struct Picture {
// 'explicit': no accidental cast from string to Picture
explicit Picture(const string &filename) { /* load image from file */ }
// no accidental construction, i.e. temporaries and the like
Picture() = delete;
// no copy
Picture(const Picture&) = delete;
// no assign
Picture& operator=(const Picture&) = delete;
// no move
Picture(Picture&&) = delete;
// no move-assign
Picture& operator=(Picture&&) = delete; // return type correct?
};
Run Code Online (Sandbox Code Playgroud)
这会删除每个默认的编译器实现,只留下析构函数,对吧?没有它,我猜这个类(几乎)无法使用,但我也可以删除它,对吗?
Picture&move-assign 的返回类型operator=(Picture&&)是否正确?如果我Picture&&为回归类型写的,它会有所作为吗?
c++ operator-overloading rvalue-reference move-semantics c++11
为了使这个代码与C++ 11引用限定符按预期工作,我必须引入一个std::move(*this)听起来不对的代码.
#include<iostream>
struct A{
void gun() const&{std::cout << "gun const&" << std::endl;}
void gun() &&{std::cout << "gun&&" << std::endl;}
void fun() const&{gun();}
void fun() &&{std::move(*this).gun();} // <-- is this correct? or is there a better option
};
int main(){
A a; a.fun(); // prints gun const&
A().fun(); // prints gun&&
}
Run Code Online (Sandbox Code Playgroud)
有些事情听起来不对劲.有std::move必要吗?这是推荐使用吗?目前,如果我不使用它,我会遇到gun const&两种情况,这不是预期的结果.
(似乎*this总是隐式和左值引用,这是有道理的,但然后是逃避使用的唯一方法move)
用clang 3.4和测试gcc 4.8.3.
编辑:这是我从@hvd回答中理解的:
1)std::move(*this)在语法和概念上是正确的
2)但是,如果 …
在C++11我们可以将对象的所有权转移到另一个unique_ptr使用std::move().所有权转移后,放弃所有权的智能指针变为null并get()返回nullptr.
std::unique_ptr<int> p1(new int(42));
std::unique_ptr<int> p2 = std::move(p1); // Transfer ownership
Run Code Online (Sandbox Code Playgroud)
在将所有权转让给另一个所有权的情况下,这有什么用unique_ptr?
灵感来自帖子为什么析构函数会禁用隐式移动方法的生成?,我想知道默认的虚拟析构函数是否也是如此,例如
class WidgetBase // Base class of all widgets
{
public:
virtual ~WidgetBase() = default;
// ...
};
Run Code Online (Sandbox Code Playgroud)
由于该类旨在成为窗口小部件层次结构的基类,因此我必须定义其析构函数virtual,以避免在使用基类指针时出现内存泄漏和未定义的行为.另一方面,我不想阻止编译器自动生成移动操作.
默认的虚拟析构函数是否会阻止编译器生成的移动操作?
Alex Stepanov将常规类型定义为满足复制和相等性的某些属性的类型.既然C++ 11已经将移动语义添加到泛型编程领域,那么Stepanov的定义就不再完整了.我正在寻找关于常规类型的一个很好的参考,包括它们与移动语义的交互.
在"C++ Concurrency in Action"一书中阅读以下方法
std::unique_lock<std::mutex> wait_for_data()
{
std::unique_lock<std::mutex> head_lock(head_mutex);
data_cond.wait(head_lock,[&]{return head.get()!=get_tail();});
return std::move(head_lock);
}
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么返回时head_lock是std :: move-ed.我对移动用法和RVO的观念和直觉与C++ 11 rvalues中共享的观点相匹配,并且移动了语义混淆(return语句)
但我倾向于相信作者更了解.有人可以澄清什么时候std :: move返回值更好,是否有关于锁的具体内容?谢谢.
为什么我允许std::move在包含具有已删除移动语义的类型的字段的类上使用(情况1),但是不允许在这样的类的实例上使用它(情况2)?
我理解案例2.我已经明确删除了移动构造函数,所以如果我试图移动它,我会收到错误.但我希望在案例1中也会出现这种情况,这样的类也在被移动.
class TestNonMovable {
std::string ss;
public:
TestNonMovable(){}
TestNonMovable(const TestNonMovable&) {}
TestNonMovable(TestNonMovable&&) = delete;
};
class SomeClass {
TestNonMovable tnm;
};
int main() {
// case1: This compiles, my understanding is that for SomeClass::tnm compiler will use copy constrctor
SomeClass sc1;
SomeClass sc2 = std::move(sc1);
// case2: This does not compile, move constructor is explicitly deleted, compiler will not try using copy constructor
TestNonMovable tnm;
TestNonMovable tnm2 = std::move(tnm); //error: use of deleted function 'TestNonMovable::TestNonMovable(TestNonMovable&&)'
}
Run Code Online (Sandbox Code Playgroud) 外部资源(如std::vector<T>或std::string)的"值类型"问题是复制它们往往非常昂贵,并且副本是在各种上下文中隐式创建的,因此这往往是性能问题.C++ 0x对这个问题的回答是移动语义,它在概念上基于资源窃取的思想,并且由rvalue引用技术驱动.
D是否有类似于移动语义或右值引用的东西?
是否可以通过使用移动语义将临时std :: map的内容插入temp到另一个std :: map中m,以便临时值不被复制并重用?
让我们说有一个:
std::map<int, Data> temp;
std::map<int, Data> m;
Run Code Online (Sandbox Code Playgroud)
从复制值的一种方法temp为m是:
m.insert(temp.begin(),temp.end());
Run Code Online (Sandbox Code Playgroud)
我怎样才能移动的temp元素融入m,而不是复制?