我正在尝试这样的事情:
class MyClass
{
public:
explicit MyClass(int) {...};
MyClass(MyClass&& that) { swap(that); }
private:
MyClass(const MyClass&); // disabled, pre-C++11 syntax
MyClass& operator=(const MyClass&); // disabled, pre-C++11 syntax
};
现在我有一个列表,我通过emplace插入它们,我正在尝试做这样的事情。
std::list<MyClass> lst;
std::remove_if(lst.begin(), lst.end(), [&,this](MyClass& mcl) { return mcl.is_foo();});
在gcc 4.6.x上,我不断收到此错误:
In file included from /usr/include/c++/4.6/algorithm:63:0,
from simple_file_cache.cpp:5:
file_cache_entry.h: In function ‘_FIter std::remove_if(_FIter, _FIter, _Predicate)
[with_FIter = std::_List_iterator<MyClass>, _Predicate =
AnotherClass::foo_bar(std::tuple<unsigned int, unsigned int>)::<lambda(MyClass&)>]’:
anotherclass.cpp:225:11: instantiated from here
anotherclass.h:68:18: error: ‘MyClass& MyClass::operator=(const MyClass&)’ is private
/usr/include/c++/4.6/bits/stl_algo.h:1149:13: error: within this context
make: *** [simple_file_cache.o] Error 1
为什么要寻找复制构造函数?
答案 0 :(得分:4)
您需要为remove_if
定义移动任务 - 运算符。如果存在用户声明的副本赋值运算符(或用户声明的副本ctor,或者dtor,或者......),则不会隐式声明它。
以下似乎是在g ++ 4.6下编译的:
#include <list>
#include <algorithm>
class MyClass
{
public:
explicit MyClass(int) {};
MyClass(MyClass&&) {}
MyClass& operator=(MyClass&&) {return *this;}
private:
MyClass(const MyClass&); // disabled, pre-C++11 syntax
MyClass& operator=(const MyClass&); // disabled, pre-C++11 syntax
};
int main()
{
std::list<MyClass> lst;
// compiles, but why use that:
//std::remove_if(lst.begin(), lst.end(), [](MyClass& mcl) { return true; });
// also compiles, makes more sense to me (but that depends on the context):
lst.remove_if([](MyClass& mcl) { return true; });
}
请注意,如果可以保证,则应考虑同时移动noexcept
。
如果要将列表的某些元素移动到列表的末尾,我宁愿使用基于splice
的算法。例如,
template<class value_type, class allocator, class F>
//typename std::list<value_type, allocator>::iterator
void
move_to_end_if(std::list<value_type, allocator>& list, F condition)
{
if(list.size() < 2) return; //list.end();
auto const former_last = std::prev(list.end());
for(auto i = list.begin(); true; ++i)
{
if(condition(*i))
{
list.splice(list.end(), list, i);
}
if(i == former_last) break;
}
// return ????;
}
这会将满足条件的所有元素移动到列表的实际(当前)末尾,保留它们的相对顺序。
注意:算法应该将迭代器返回到未移动序列的末尾,或list::end()
。还没有找到一种优雅的方式来做到这一点。