#include <range/v3/all.hpp>
#include <vector>
#include <string>
#include <deque>
using namespace std::literals;
int main()
{
auto src = std::vector{"123"s, "456"s, "789"s};
auto movable_rng = ranges::subrange(
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end()));
auto dst = ranges::to<std::deque<std::string>>(movable_rng);
for (auto e : src)
{
std::cout << e << std::endl;
}
for (auto e : dst)
{
std::cout << e << std::endl;
}
}
使用clang 10编译,输出为:
123
456
789
123
456
789
正如我所期望的,结果应该是:
""
""
""
123
456
789
为什么range-v3甚至迭代器也不会移动元素std::move_iterator
?
cppreference上的示例代码具有此:
std::string str1;
std::string str2 { "alpha" };
...
str1 = std::move(str2);
std::cout << std::quoted(str1) << ' ' // "alpha"
<< std::quoted(str2) << '\n'; // "" or "alpha" (unspecified)
可能是由于小的字符串优化,所以不需要将移出的字符串为空。允许在移动后保持不变。唯一的要求是它仍然处于有效状态。
从对象移出会使它处于有效但未定义的状态。由于您的字符串都很小,因此很有可能字符都存储在对象内部而不是堆(SSO)中。这使得在“移出”字符串之后,将移出的字符串归零的效率较低(略)。