5

我有一个实例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;
}

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

uptrfncall.cpp:在函数“int main()”中:
uptrfncall.cpp:27:25:错误:使用已删除的函数 'std::unique_ptr::unique_ptr(const std::unique_ptr&) [with _Tp = int; _Dp = std::default_delete]'
  doStuff(std::move(*cur)); // 第 25 行,编译器错误
                         ^
在 /usr/include/c++/4.8/memory:81:0 包含的文件中,
                 来自 uptrfncall.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:273:7:错误:在此处声明
       unique_ptr(const unique_ptr&) = 删除;
       ^
uptrfncall.cpp:9:10: 错误: 初始化 'void doStuff(std::unique_ptr)' 的参数 1
     无效doStuff(unique_ptr ptr)
          ^

请注意,它完美地适用于 ,vector但不适用于set. 由于setis not constbegin()调用不应返回 a const_iterator,因此在取消引用迭代器时应该可以移动值。为什么这不编译?

4

2 回答 2

10

该集合可能不是 const,但其中的元素是。你不能修改一个集合的元素,因为它不能保证它保持它的不变量。

于 2013-08-13T05:40:24.013 回答
1

代码行std::set是基于红黑树创建的,集合的迭代器类型与树的键类型相同,显然你不能改变键的值。

于 2018-12-12T07:22:05.863 回答