我一直在玩std::unique_ptr
和std::for_each
算法来学习它们,然后我收到了这个错误"试图引用一个删除的函数",当我试图将一些变量从一个容器(std::map
)移动到另一个。
此代码当前在成员函数中执行。Foo
只是一个泛型类。
std::for_each(m_list1.begin(), m_list1.end(),
[&](std::pair<std::size_t,std::unique_ptr<Foo>> data_pair)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
});
m_list1.clear();
我尝试了各种方法,但问题仍然存在。然后我尝试使用基于范围的for代替,突然它工作了。
for (auto& data_pair : m_list1)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
m_list1.clear();
我想知道的是为什么第二段代码执行没有问题,而第一段代码产生了错误。
如果你需要更具体的信息,尽管问。如果在我的编码风格有不好的做法,请建议如何使它更好。
您的for_each
代码中有两个错误。首先,map::value_type
是pair<const Key, Value>
。其次,您的lambda表达式按值接受参数,这意味着它试图复制unique_ptr
,因此出现错误。要解决这个问题,可以通过引用接受实参。
[&](std::pair<const std::size_t, std::unique_ptr<Foo>>& data_pair)
// ^^^^^ ^^^
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
一个更好的选择是不显式地提及这些类型,而是使用decltype
[&](decltype(m_list1)::value_type& data_pair)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
现在,基于范围的for
工作了,因为您通过使用for(auto& data_pair : m_list1)
将map
的元素绑定到引用。如果您使用for(auto data_pair : m_list1)
,则会遇到与以前相同的错误,因为它试图复制元素。