C++ move():向量中还剩下什么?
C++ move(): what's left in the vector?
我有一段代码,其中 vector
中的元素是 int
和 string
对。然后我想将所有元素从 vector
移动到 unordered_map<int, string>
:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
#include <vector>
using namespace std;
template <typename C>
void print(const C& container) {
for (const auto& ele : container) {
cout << "(" << ele.first << ", " << ele.second << "), ";
}
cout << endl;
}
int main() {
vector<pair<int, string>> v {
{1, "one"},
{2, "two"},
{3, "three"},
{4, "four"},
{5, "five"}
};
unordered_map<int, string> uMap;
move(begin(v), end(v), inserter(uMap, begin(uMap)));
cout << "In unordered_map:" << endl;
print(uMap);
cout << endl << "In vector:" << endl;
print(v);
return 0;
}
我不明白的是结果:
In unordered_map:
(5, five), (4, four), (3, three), (2, two), (1, one),
In vector:
(1, ), (2, ), (3, ), (4, ), (5, ),
为什么那些整数留在 vector
中?我认为 move()
函数会将所有元素从 vector
移动到 unordered_map
,这样就不会在 vector
?
中留下任何东西
来自 cppreference:
Moves the elements in the range [first, last), to another range beginning at d_first, starting from first and proceeding to last - 1. After this operation the elements in the moved-from range will still contain valid values of the appropriate type, but not necessarily the same values as before the move.
因为该算法在迭代器上运行,所以它实际上无法从向量中删除元素。它们仍然存在,并且它们可以具有与以前相同的值(但不一定)。
而且字符串仍然存在于向量中。从 std::string
移动后,它处于有效但未指定的状态。在这种情况下,字符串为空。
通俗地说,移出对象的唯一要求是以后可以安全地销毁它。在 int
的情况下,最好的办法是什么都不做。移动不会破坏对象,也不会将其从容器中移除。对象仍在向量中,只是它们现在处于移动状态,对于 int
,恰好与以前相同。
"move" 在这里并不是真正的意思。
是的,这很混乱。
地图中的新元素将从矢量中的元素移动构建。这可能涉及从 vector 中的元素窃取资源(特别是,动态分配的字符串数据现在将属于新元素,并与旧元素分离)。
但这实际上并没有删除原始元素。他们还在那里,处于搬离状态。您需要自己 clear()
向量。
至:
std::move
is in some ways an unfortunate term. But it was much shorter than std::suck_out_the_guts_and_transplant_them_into_another_object_maybe
.
std::move
实际上并没有移动任何东西。它只是执行一个右值转换并告诉编译器你不再关心那个对象会发生什么。在 int 的情况下,编译器决定以最有效的方式进行复制。
您可以在此处阅读有关 C++ 移动语义的更多信息:C++ move semantics
我有一段代码,其中 vector
中的元素是 int
和 string
对。然后我想将所有元素从 vector
移动到 unordered_map<int, string>
:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
#include <vector>
using namespace std;
template <typename C>
void print(const C& container) {
for (const auto& ele : container) {
cout << "(" << ele.first << ", " << ele.second << "), ";
}
cout << endl;
}
int main() {
vector<pair<int, string>> v {
{1, "one"},
{2, "two"},
{3, "three"},
{4, "four"},
{5, "five"}
};
unordered_map<int, string> uMap;
move(begin(v), end(v), inserter(uMap, begin(uMap)));
cout << "In unordered_map:" << endl;
print(uMap);
cout << endl << "In vector:" << endl;
print(v);
return 0;
}
我不明白的是结果:
In unordered_map:
(5, five), (4, four), (3, three), (2, two), (1, one),
In vector:
(1, ), (2, ), (3, ), (4, ), (5, ),
为什么那些整数留在 vector
中?我认为 move()
函数会将所有元素从 vector
移动到 unordered_map
,这样就不会在 vector
?
来自 cppreference:
Moves the elements in the range [first, last), to another range beginning at d_first, starting from first and proceeding to last - 1. After this operation the elements in the moved-from range will still contain valid values of the appropriate type, but not necessarily the same values as before the move.
因为该算法在迭代器上运行,所以它实际上无法从向量中删除元素。它们仍然存在,并且它们可以具有与以前相同的值(但不一定)。
而且字符串仍然存在于向量中。从 std::string
移动后,它处于有效但未指定的状态。在这种情况下,字符串为空。
通俗地说,移出对象的唯一要求是以后可以安全地销毁它。在 int
的情况下,最好的办法是什么都不做。移动不会破坏对象,也不会将其从容器中移除。对象仍在向量中,只是它们现在处于移动状态,对于 int
,恰好与以前相同。
"move" 在这里并不是真正的意思。
是的,这很混乱。
地图中的新元素将从矢量中的元素移动构建。这可能涉及从 vector 中的元素窃取资源(特别是,动态分配的字符串数据现在将属于新元素,并与旧元素分离)。
但这实际上并没有删除原始元素。他们还在那里,处于搬离状态。您需要自己 clear()
向量。
至
std::move
is in some ways an unfortunate term. But it was much shorter thanstd::suck_out_the_guts_and_transplant_them_into_another_object_maybe
.
std::move
实际上并没有移动任何东西。它只是执行一个右值转换并告诉编译器你不再关心那个对象会发生什么。在 int 的情况下,编译器决定以最有效的方式进行复制。
您可以在此处阅读有关 C++ 移动语义的更多信息:C++ move semantics