Tag: 移动语义

默认的Move构造函数是否定义为noexcept?

看起来,一个向量将检查移动构造函数是否被标记为noexcept,然后决定在重新分配时是移动还是复制元素。 默认的移动构造函数是否定义为noexcept? 我看到下面的文档,但没有指定这个。 http://en.cppreference.com/w/cpp/language/move_constructor 隐式声明的移动构造函数 如果没有为类types(结构体,类或联合体)提供用户定义的移动构造函数,并且以下所有条件都成立:没有用户声明的复制构造函数,则没有用户声明的复制赋值运算符用户声明的移动赋值运算符没有用户声明的析构函数隐式声明的移动构造函数未被定义为删除由于下一节中详细说明的条件,那么编译器将声明一个移动构造函数作为它的类的内联公共成员签名T :: T(T &&)一个类可以有多个移动构造函数,例如T :: T(const T &&)和T :: T(T &&)。 如果存在一些用户定义的移动构造函数,则用户仍然可以强制生成隐式声明的移动构造函数,其关键字为default。

为什么Visual Studio在这种情况下不执行返回值优化(RVO)

我正在回答一个问题,并build议按值返回一个大的types,因为我确信编译器会执行返回值优化(RVO) 。 但后来有人向我指出,Visual Studio 2013在我的代码上没有执行RVO。 我在这里发现了一个关于Visual Studio未能执行RVO的问题,但是在这种情况下,结论似乎是,如果真的很重要,Visual Studio将执行RVO。 在我的情况下,它确实很重要,它对性能的影响很大,我已经通过性能分析结果进行了确认。 这是简化的代码: #include <vector> #include <numeric> #include <iostream> struct Foo { std::vector<double> v; Foo(std::vector<double> _v) : v(std::move(_v)) {} }; Foo getBigFoo() { std::vector<double> v(1000000); std::iota(v.begin(), v.end(), 0); // Fill vector with non-trivial data return Foo(std::move(v)); // Expecting RVO to happen here. } int main() { std::cout << […]

为什么有些人使用交换分配移动?

例如,stdlibc ++具有以下内容: unique_lock& operator=(unique_lock&& __u) { if(_M_owns) unlock(); unique_lock(std::move(__u)).swap(*this); __u._M_device = 0; __u._M_owns = false; return *this; } 为什么不直接将这两个__u成员分配给* this? 不交换意味着__u被分配了*这个成员,只是以后再分配0和false …在这种情况下交换是做不必要的工作。 我错过了什么? (unique_lock :: swap只是在每个成员上执行std :: swap)

按值或引用传递std :: string

可能重复: 是传递const std :: string&作为参数的日子吗? 如果支持移动语义,我应该通过值或通过引用传递std::string (未内联函数)? 那么使用小string优化(SSO)的实现呢?

是一个`=默认`移动构造函数等价于成员移动构造函数?

这是 struct Example { int a, b; Example(int mA, int mB) : a{mA}, b{mB} { } Example(const Example& mE) : a{mE.a}, b{mE.b} { } Example(Example&& mE) : a{move(mE.a)}, b{move(mE.b)} { } Example& operator=(const Example& mE) { a = mE.a; b = mE.b; return *this; } Example& operator=(Example&& mE) { a = move(mE.a); b = move(mE.b); […]

为什么派生类移动时可以构build基类不是?

考虑下面的例子: #include <iostream> #include <string> #include <utility> template <typename Base> struct Foo : public Base { using Base::Base; }; struct Bar { Bar(const Bar&) { } Bar(Bar&&) = delete; }; int main() { std::cout << std::is_move_constructible<Bar>::value << std::endl; // NO std::cout << std::is_move_constructible<Foo<Bar>>::value << std::endl; // YES. Why?! } 为什么编译器生成一个移动构造函数,尽pipe基类是不可移动的可构造的? 这是标准还是编译器错误? 是否有可能“完美地宣传”从基地到派生class的build设?

应该将C ++ 11中的所有/大多数setter函数写成接受通用引用的函数模板吗?

考虑一个具有N成员variables的类X ,每个variables都是可 复制的和可移动的 ,以及N相应的设置函数。 在C ++ 98中, X的定义可能如下所示: class X { public: void set_a(A const& a) { _a = a; } void set_b(B const& b) { _b = b; } … private: A _a; B _b; … }; 上面的类X Setter函数可以绑定到左值和右值参数。 根据实际的参数,这可能会导致创build一个临时的,最终会导致一个副本分配; 由于这个原因,这种devise不支持不可复制的types。 使用C ++ 11,我们可以移动语义,完美转发和通用引用(Scott Meyers的术语),通过以这种方式重写它们,可以更有效地使用setter函数: class X { public: template<typename T> void set_a(T&& a) […]

对于已经构build的对象,C ++ 11的push_back()使用std :: move和emplace_back()的效率

在C ++ 11中,对于push_back()来说, emplace_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) 另外,在上面的例子中,是否有任何好处来替代: myvector.emplace_back(std::move(mystring)); 或者这里的举动完全是多余的,还是没有效果?

std :: move()如何将值传递给RValues?

我只是发现自己不完全理解std::move()的逻辑。 起初,我google了,但似乎只有关于如何使用std::move()文档,而不是它的结构如何工作。 我的意思是,我知道模板成员函数是什么,但是当我查看VS2010中的std::move()定义时,它仍然是令人困惑的。 std :: move()的定义如下。 template<class _Ty> inline typename tr1::_Remove_reference<_Ty>::_Type&& move(_Ty&& _Arg) { // forward _Arg as movable return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg); } 对我来说最奇怪的是参数(_Ty && _Arg),因为当我像下面看到的那样调用函数时, // main() Object obj1; Object obj2 = std::move(obj1); 它基本上等于 // std::move() _Ty&& _Arg = Obj1; 但是,正如你已经知道的那样,你不能直接将LValue链接到RValue引用,这使我认为它应该是这样的。 _Ty&& _Arg = (Object&&)obj1; 然而,这是荒谬的,因为std :: move()必须适用于所有的值。 所以我想完全明白这是如何工作的,我也应该看看这些结构。 template<class _Ty> struct _Remove_reference { […]

为什么我会std ::移动一个std :: shared_ptr?

我一直在查看Clang的源代码 ,发现这个代码片段: void CompilerInstance::setInvocation( std::shared_ptr<CompilerInvocation> Value) { Invocation = std::move(Value); } 为什么我要std::move一个std::shared_ptr ? 在共享资源上转让所有权有没有意义? 为什么我不这样做呢? void CompilerInstance::setInvocation( std::shared_ptr<CompilerInvocation> Value) { Invocation = Value; }