为什么我不能使用迭代器将unique_ptr从集合移动到函数参数?

Chr*_*ris 3 c++ iterator set unique-ptr move-semantics

我有一个setunique_ptr情况,并希望他们都作为参数传递给函数.以下代码演示的示例.

#include <memory>
#include <set>
#include <vector>

using std::set;
using std::unique_ptr;
using std::vector;

void doStuff(unique_ptr<int> ptr)
{
  // doing stuff...
}

int main()
{
  vector<unique_ptr<int>> ptrVector;
  set<unique_ptr<int>> ptrSet;

  for (auto cur = ptrVector.begin(); cur != ptrVector.end(); cur++)
  {
    doStuff(std::move(*cur));
  }

  for (auto cur = ptrSet.begin(); cur != ptrSet.end(); cur++)
  {
    doStuff(std::move(*cur));
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会导致以下编译器错误(GCC 4.8.1):

uptrfncall.cpp: In function ‘int main()’:
uptrfncall.cpp:27:25: error: use of deleted function ‘std::unique_ptr::unique_ptr(const std::unique_ptr&) [with _Tp = int; _Dp = std::default_delete]’
  doStuff(std::move(*cur)); // line 25, compiler error
                         ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from uptrfncall.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:273:7: error: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^
uptrfncall.cpp:9:10: error:   initializing argument 1 of ‘void doStuff(std::unique_ptr)’
     void doStuff(unique_ptr ptr)
          ^

请注意,它可以完美地工作,vector但不适用于set.如果set不是const,则begin()调用不应返回a,const_iterator因此在解除引用迭代器时应该可以移动值.为什么这不编译?

GMa*_*ckG 9

该集合可能不是const,但其中的元素是.您无法修改集合的元素,因为它无法保证它保持其不变量.

  • @Chris:为了与其他容器保持一致,它有两个名称.然而,它们是相同的(http://coliru.stacked-crooked.com/view?id=4c2f475de8f7fe11baa826bcb62d0af0-f674c1a6d04c632b71a62362c0ccfc51). (3认同)
  • 但见http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3645.pdf关于如何可以这样做的建议(不接受). (3认同)