即使迭代器为std :: move_iterator,为什么range-v3也不移动元素?

问题描述 投票:-1回答:2
#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

c++ standards move-semantics rvalue-reference range-v3
2个回答
3
投票

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)

可能是由于小的字符串优化,所以不需要将移出的字符串为空。允许在移动后保持不变。唯一的要求是它仍然处于有效状态。


1
投票

从对象移出会使它处于有效但未定义的状态。由于您的字符串都很小,因此很有可能字符都存储在对象内部而不是堆(SSO)中。这使得在“移出”字符串之后,将移出的字符串归零的效率较低(略)。

© www.soinside.com 2019 - 2024. All rights reserved.