为什么remove_if(...,lambda)表达式需要赋值运算符? [英] Why does remove_if( ..., lambda ) expression require the assignment operator?

查看:201
本文介绍了为什么remove_if(...,lambda)表达式需要赋值运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个代码(简体):

I have this code (simplified) :

std::vector<Session> sessions;
// ...
std::remove_if( sessions.begin(), sessions.end(), 
   [] (const Session& s) {
      return false;
   }
);

编译时(在Visual Studio 2013 Update 1中),出现以下错误:

When I compile it (in Visual Studio 2013 Update 1) I get the following error:

algorithm(1759): error C2280: 'Session &Session::operator =(const Session &)' : attempting to reference a deleted function
   Session.h(78) : see declaration of 'Session::operator ='

实际上,我已经在Session类中删除了operator=,如下所示:

Indeed, I have deleted operator= in the Session class like this:

Session& operator= (const Session& that) = delete;

我的问题是:为什么使用lambda表达式的remove_if为什么需要赋值运算符?一个Session对象分配给另一个对象在哪里?

My question is: why does that remove_if using a lambda expression require the assignment operator? Where is one Session object assigned to another?

更新:正如@nosid和@Praetorian remove_if所述,需要移动或复制构造函数&赋值运算符.根据C ++ 11标准,移动构造函数/赋值运算符应已由编译器自动生成.不幸的是 Visual Studio 2013不能做到这一点.由于该类不可复制,因此remove_if也无法求助于复制,因此编译器将显示错误.我通过手动实现move构造函数和move赋值运算符来解决它.

Update: As explained by @nosid and @Praetorian remove_if requires either move or copy constructor & assignment operator. According to the C++11 standard the move constructor/assignment operator should have been auto-generated by the compiler. Unfortunately Visual Studio 2013 does not do that. Since the class is not copyable remove_if cannot resort to copying, either, so the compiler displays the error. I fixed it by manually implementing a move constructor and a move assignment operator.

推荐答案

该错误不是由lambda表达式引起的. lambda表达式很好,如果您将remove_if替换为all_of:

The error is not caused by the lambda expression. The lambda expression is fine, as can be seen if you replace remove_if with all_of:

// OK
std::all_of(_sessions.begin(), _sessions.end(), 
    [](const Session& session) { return false; });

该错误是由算法std::remove_if引起的.通过以以下方式移动范围中的元素来完成删除,即要删除的元素出现在范围的开头.因此,需要复制或移动作业.

The error is caused by the algorithm std::remove_if. Removing is done by shifting the elements in the range in such a way that the elements that are not to be removed appear in the beginning of the range. For that reason, a copy or move assignment is required.

对于需要复制或移动分配操作的其他算法,即使使用的它们没有lambda表达式,您也会看到相同的错误消息.这是一个示例:

You will see the same error message for other algorithm that require copy or move assignment operations, even if they are used without a lambda expression. Here is an example:

// ERROR: Session& operator=(const Session&) is private
std::move(std::next(_sessions.begin()), _sessions.end(), _sessions.begin());

这篇关于为什么remove_if(...,lambda)表达式需要赋值运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆