c ++尝试引用已删除的函数

时间:2014-06-08 04:10:20

标签: c++ unique-ptr

我一直在使用std::unique_ptrstd::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();

我想知道的是为什么第二个代码执行没有问题,而第一个代码产生了错误。

如果您需要更具体的信息,请询问。如果我的编码风格有不好的做法,请告知如何使其更好。

1 个答案:

答案 0 :(得分:1)

您的for_each代码中存在两个错误。首先,map::value_typepair<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有效,因为您使用mapfor(auto& data_pair : m_list1)的元素绑定到引用。如果您改为使用for(auto data_pair : m_list1),那么您将遇到与以前相同的错误,因为它曾试图复制这些元素。