我第一次尝试编写基于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
}
答案 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>>
,但如果vector
或unique_pointer
具有专业化,则可能会导致热闹的未定义行为。 不要尝试,这不值得。