如何编写其指针和数据为const的unique_ptr

时间:2014-04-07 13:07:47

标签: c++ unique-ptr

我第一次尝试编写基于for循环的范围来迭代unique_ptrs我写道:

std::vector<std::unique_ptr<Foo>> vec;
// Initialize vec

for (auto v : vec) // error
{}

然后我意识到这是尝试创建每个元素的副本,这对于unique_ptr是没有意义的。所以我写了它作为参考:

for (auto& v : vec)
{}

在它前面添加一个const使我无法更改指针。

for (const auto& v : vec)
{
   v = nullptr; // error (good!)
}

如何编写它,以便指向的数据无法更改?例如,以下代码不应编译。

for (??? v : vec)
{
   v->func();
}

class Foo
{
public:
   void func();

private:
   bool mBar;
}

Foo::func()
{
   mbar = true; // Should cause error
}

2 个答案:

答案 0 :(得分:5)

要防止数据被修改,请在指针的模板参数中包含const

std::vector<std::unique_ptr<const Foo>> vec;

我认为你的指针本身const会有问题。原因是向量必须能够在内部复制指针对象(例如,在调整容器大小时)。使用unique_ptr,这意味着必须在实例之间传输所有权,这意味着它必须是可变的(而不是const)。

要使指针本身const,我认为你有两个主要选择:使用const shared_ptr<>的向量,或const unique_ptr<>的数组(即固定大小)。 / p>

答案 1 :(得分:3)

为此,您的unique_pointer必须针对const限定类型进行实例化,如下所示:

std::vector<std::unique_ptr<const Foo>> vec;

但也许使用迭代器在循环开始时初始化一个常量引用就足够了,编译器应该优化它:

for (const auto& v_iter : vec) {
    const auto& x = *v_iter;
    do_things(...);
}

其他一切都是hackery。

可能有用的是将vector<unique_pointer<Foo>>重新解释为vector<unique_pointer<const Foo>>,但如果vectorunique_pointer具有专业化,则可能会导致热闹的未定义行为。 不要尝试,这不值得。