Range-v3 Flattern с ходом - PullRequest
       59

Range-v3 Flattern с ходом

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

Я пытаюсь сгладить контейнер контейнера в одно измерение, используя views :: join и views :: move, но мне трудно понять разницу между move сначала, а затем join VS, join и затем move , Try2 работал, как и ожидалось, но может ли кто-нибудь помочь мне понять, что происходит под капотом, так что Try1 заканчивает копирование? где-то движение не сработало. Спасибо !

wandbox ссылка на код: https://wandbox.org/permlink/BeFI3wjBiUPbsMA2

#include <iostream>
#include <vector>
#include <string>
#include <range/v3/all.hpp>

int main()
{     
    auto words = std::vector<std::vector<std::string>>{
        {"Hello", "World"},
        {"ni","hao"}
    };
    // Try1
    auto result1 = words
        | ranges::views::move
        | ranges::views::join
        | ranges::to<std::vector<std::string>>();

    std::cout<<ranges::views::all(ranges::views::join(words))<<std::endl;
    //[Hello,World,ni,hao]

    // Try2   
    auto result2 = words
        | ranges::views::join
        | ranges::views::move
        | ranges::to<std::vector<std::string>>();

    std::cout<<ranges::views::all(ranges::views::join(words))<<std::endl;
    //[,,,]
}

Ответы [ 2 ]

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

move означает, что перемещенный объект находится в допустимом, но неопределенном состоянии. Это не означает , что удаленный объект будет очищен. Таким образом, оба выхода совершенно верны.

Я предполагаю, что первый move не стирает исходные строки из-за оптимизации маленьких строк, где это может быть более эффективным.

На самом деле, если первый move действительно переместился из words, то result2 будет иметь все пустые строки. Опять же, это будет полностью действительным.

0 голосов
/ 25 апреля 2020

Это ответ «как исправить», без объяснения «почему». Я не знаю, как это поведение документировано, не указано в следующем C ++ 20.

В вашем примере достаточно добавить вторую ranges::views::move между join и to операциями.

auto result1 = words
    | ranges::views::move
    | ranges::views::join
    | ranges::views::move
    | ranges::to<std::vector<std::string>>();

std::cout<<ranges::views::all(ranges::views::join(words))<<std::endl;

https://wandbox.org/permlink/ONU5sn4pQrMGWvnD

...