我一直在使用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 (auto& data_pair : m_list1)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
m_list1.clear();
我想知道的是为什么第二个代码执行没有问题,而第一个代码产生了错误。
如果您需要更具体的信息,请询问。如果我的编码风格有不好的做法,请告知如何使其更好。
答案 0 :(得分:1)
您的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
有效,因为您使用map
将for(auto& data_pair : m_list1)
的元素绑定到引用。如果您改为使用for(auto data_pair : m_list1)
,那么您将遇到与以前相同的错误,因为它曾试图复制这些元素。