基于范围的循环、唯一指针和移动语义
Range-based loop, unique pointers, and move semantics
这是一个类似于我的代码:
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是不合法的。
我 "skimmed" 虽然公开可用的 C++11 草案,但没有找到关于该主题的任何说明。
谁能告诉我上面的代码是否合法?
您的代码绝对合法且定义明确。没有什么能阻止您在迭代期间修改序列的元素,移动只是一种修改形式。
请记住不要在循环后尝试使用这些指针。
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));
}
这就是基于范围的 for 循环所做的;使用迭代器并为您取消引用它,这样您就不会真正接触迭代器。
这是一个类似于我的代码:
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是不合法的。
我 "skimmed" 虽然公开可用的 C++11 草案,但没有找到关于该主题的任何说明。
谁能告诉我上面的代码是否合法?
您的代码绝对合法且定义明确。没有什么能阻止您在迭代期间修改序列的元素,移动只是一种修改形式。
请记住不要在循环后尝试使用这些指针。
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));
}
这就是基于范围的 for 循环所做的;使用迭代器并为您取消引用它,这样您就不会真正接触迭代器。