Почему range-v3 не перемещает элементы, даже если итератор - std :: move_iterator? - PullRequest
0 голосов
/ 24 апреля 2020
#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 с libc ++ и вывод:

123
456
789
123
456
789

Как я и ожидал, результат должен быть:

""
""
""
123
456
789

Почему диапазоны -v3 не перемещать элементы, даже итератор std::move_iterator?

======= Обновление =======

My Версия диапазонов: range-v3-0.10.0. Даже если я заменил std::string на std::vector<char>, проблема все еще воспроизводима на моем linux docker, и g cc, и clang дают одинаковый результат.

Однако, тот же код в порядке на godbolt.org , но я не уверен, что версия диапазонов диапазонов на godbold.org равна 3.0.10.

Ответы [ 2 ]

6 голосов
/ 24 апреля 2020

Пример кода на 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)

Вероятно, из-за небольших оптимизаций строки, нет требования, чтобы строка перемещения была пустой. Это разрешается оставлять без изменений после переезда. Единственное требование заключается в том, что он все еще находится в действительном состоянии.

3 голосов
/ 24 апреля 2020

Перемещение от объекта оставляет его в допустимом, но не определенном состоянии. Вполне возможно, что, поскольку все ваши строки маленькие, все символы хранятся внутри объекта, а не в куче (SSO). Это делает менее эффективным (незначительным) обнуление перемещенной строки после «перемещения» из нее.

...