C++ c++;(为什么)移动构造函数是否删除运算符=

C++ c++;(为什么)移动构造函数是否删除运算符=,c++,C++,我有一个带结构的向量 Struct S { S( double a, double b ) : a_(a), b_(b) {} double a_; double b_; S(S&&) = default; //ADDED } 我使用emplace back将s的实例添加到向量中 v.emplace_back( x, y ); 因为要保证编译器会添加一个移动构造函数,所以我认为添加一个默认的移动构造函数没有什么害处,所以我添加了注释为add

我有一个带结构的向量

Struct S {
    S( double a, double b ) : a_(a), b_(b) {}
    double a_;
    double b_;
    S(S&&) = default;   //ADDED
}
我使用emplace back将s的实例添加到向量中

v.emplace_back( x, y );
因为要保证编译器会添加一个移动构造函数,所以我认为添加一个默认的移动构造函数没有什么害处,所以我添加了注释为added的行。 然而,当我得到编译错误时,这似乎已经禁用了运算符=

/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:868: error: use of deleted function ‘S& S::operator=(const S&)’
         *__result = _GLIBCXX_MOVE(*__first);
                   ^
我不明白为什么会这样。我的S(S&&)实现方式是否错误

编辑: 使用“删除”时引发错误

v.erase(std::remove_if(v.begin(), v.end(), deleteIf), v.end());

一些旧的STL容器实现在调整底层容器的大小时使用赋值操作符。要调整大小,它们分配内存,默认构造初始对象,使用赋值操作符将对象复制到新容器中,然后释放以前的对象

在一个相关的主题上,如果你要制作一个对象,你也应该制作它


由于结构中唯一的数据成员是double's(不分配资源的基本类型),因此此结构不需要移动构造函数。

一些较旧的STL容器实现在调整基础容器大小时使用赋值运算符。要调整大小,它们分配内存,默认构造初始对象,使用赋值操作符将对象复制到新容器中,然后释放以前的对象

在一个相关的主题上,如果你要制作一个对象,你也应该制作它


由于结构中仅有的数据成员是double's(不分配资源的基本类型),因此此结构不需要移动构造函数。

将自动提供默认的复制赋值运算符(执行成员复制),除非类声明了复制赋值运算符,删除复制分配运算符,或声明移动操作。这是因为编译器假定如果您声明任何移动操作,则您的类很可能持有不应复制的数据,因此它强制您自己实现复制赋值运算符,以尝试强制执行


幻灯片30中有一个很好的图表显示了何时提供了默认构造函数和赋值运算符。

除非类声明了复制赋值运算符,删除了复制赋值运算符,否则将自动提供默认的复制赋值运算符(执行成员复制),或声明移动操作。这是因为编译器假定如果您声明任何移动操作,则您的类很可能持有不应复制的数据,因此它强制您自己实现复制赋值运算符,以尝试强制执行


幻灯片30中有一个很好的图表显示了何时提供了默认构造函数和赋值运算符。

但这是否仍然意味着先创建结构,然后复制并再次有效创建?我在这里的示例中的结构比实际的结构小很多(也不包含除原语以外的任何内容,though@chrise是的,这意味着。一些STL实现是这样工作的。其他的不行。如果对象提供移动赋值运算符或移动构造函数,我更喜欢使用移动语义的实现。请检查您的STL实现。:-)因此,添加“S&operator=(S&&)=default;”应该修复我的问题并允许移动构造?(结构可能会增长很多,所以我最好现在就正确地完成它)@是的,继续添加移动赋值操作符,看看会发生什么。你也可以添加一个常规的复制赋值操作符。好吧,编译器停止抱怨。所以,我认为这是一个好迹象。就我的理解而言,还有一个问题……这基本上相当于创建结构,然后通过std将其传递回emplace_●移动,对吗?但这是否仍然意味着结构首先创建,然后复制并有效地创建?我在我的示例中的结构比实际的结构小了一点(也不包含除原语以外的任何内容,though@chrise是的,这意味着。一些STL实现是这样工作的。其他的不行。如果对象提供移动赋值运算符或移动构造函数,我更喜欢使用移动语义的实现。请检查您的STL实现。:-)因此,添加“S&operator=(S&&)=default;”应该修复我的问题并允许移动构造?(结构可能会增长很多,所以我最好现在就正确地完成它)@是的,继续添加移动赋值操作符,看看会发生什么。你也可以添加一个常规的复制赋值操作符。好吧,编译器停止抱怨。所以,我认为这是一个好迹象。就我的理解而言,还有一个问题……这基本上相当于创建结构,然后通过std将其传递回emplace_::移动,对吗?谢谢你的幻灯片。很好的备忘单谢谢你的幻灯片。很好的备忘单