这是一个类似于我的代码:
for (auto &uptr : vector_of_unique_ptrs) { // 1
auto result = do_the_job_with_pointee(uptr.get()); // 2
record_intermidiate_result(result, std::move(uptr)); // 3
}
这里有一些指向某些对象的独特指针(第1行)。
我遍历向量(第1行)并使用指针对象(第2行)做一些工作。
工作完成后,我需要取一个结果并将所有权转移到其他地方(第3行)。
代码编译和执行没有任何问题,但我觉得在迭代期间移动iteratee是不合法的。
我通过公开发布的C ++ 11草案“撇去”,但没有找到任何有关该主题的说明。
有人可以告诉我上面的代码是否合法?
答案 0 :(得分:10)
您的代码绝对合法且定义明确。没有什么能阻止你在迭代过程中修改序列的元素,移动只是一种修改形式。
请记住,不要在循环后尝试使用这些指针。
答案 1 :(得分:5)
for (auto &uptr : vector_of_unique_ptrs)
' uptr'现在是对你制作的任何类型的unique_ptr的引用。 ' uptr'在这种情况下,它不是迭代器。因此,您的代码是安全的,因为它实际上并没有弄乱迭代器。
现在,如果您编写了这样的代码:
for(auto iter = vec.begin(); iter != vec.end(); iter++)
这将是一个不同的故事。在这个' iter'上使用std :: move在循环中间会有问题,可能不是你想要的。但就向量和循环而言,使用代码是安全的。实际上,这里有几种查看代码的方法:
//I'm calling your vector_of_unique_ptrs 'vec' for brevity
//and I'm assuming unique_ptr<int> just 'cause
//This works
for (auto iter = vec.begin(); iter != vec.end(); iter++) {
unique_ptr<int>& uptr = *iter;
auto result = do_the_job_with_pointee(uptr.get());
record_intermidiate_result(result, std::move(uptr));
}
//As does this
for (size_t i = 0; i < vec.size(); i++) {
unique_ptr<int>& uptr = vec[i];
auto result = do_the_job_with_pointee(uptr.get());
record_intermidiate_result(result, std::move(uptr));
}
这就是基于范围的循环所做的事情;使用迭代器并为您取消引用它,这样您就不会实际触摸迭代器。