переезд в контейнер unique_ptr

0

У меня есть что-то, что я хочу сделать, что очень похоже на фрагмент кода на cppreference.com для unique_ptr. Ниже приведен фрагмент. Он прекрасно компилируется.

#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <iterator>

int main()
{
    std::list<std::string> s{"one", "two", "three"};

    std::vector<std::string> v1(s.begin(), s.end()); // copy

    std::vector<std::string> v2(std::make_move_iterator(s.begin()),
                                std::make_move_iterator(s.end())); // move

    std::cout << "v1 now holds: ";
    for (auto str : v1)
            std::cout << "\"" << str << "\" ";
    std::cout << "\nv2 now holds: ";
    for (auto str : v2)
            std::cout << "\"" << str << "\" ";
    std::cout << "\noriginal list now holds: ";
    for (auto str : s)
            std::cout << "\"" << str << "\" ";
    std::cout << '\n';
}

Я действительно хочу переместить строки из s в вектор unique_ptr.

что-то вроде std::vector<std::unique_ptr<std::string>> v2(&std::make_move_iterator(s.begin()), &std::make_move_iterator(s.end()));

но это, конечно, не работает.

Я могу только заставить его делать то, что я хочу, с этим битом кода:

int main()
{
    std::list<std::string> s{"one", "two", "three"};

    std::vector<std::string> v1(s.begin(), s.end()); // copy

    std::vector<std::unique_ptr<std::string>> v2;
    for(auto& o : s)
    {
        std::unique_ptr<std::string> p ( new std::string(move(o)));
        v2.push_back(move(p));
    }

    std::cout << "\nv2 now holds: ";
    for (auto& pstr : v2)
            std::cout << "\"" << *pstr << "\" ";
    std::cout << "\noriginal list now holds: ";
    for (auto str : s)
            std::cout << "\"" << str << "\" ";
    std::cout << '\n';
} 

Есть ли способ переместить ресурсы в контейнер unique_ptrs в одной строке?

Теги:
c++11
unique-ptr

1 ответ

3

Да, если вы используете функцию make_unique рекомендует Herb Sutter:

template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
    return std::unique_ptr<T> ( new T( std::forward<Args>(args)... ) );
}

int main()
{
    std::list<std::string> s{"one", "two", "three"};

    std::vector<std::unique_ptr<std::string>> v2;
    std::transform(begin(s), end(s), std::back_inserter(v2),
            &make_unique<std::string, std::string&>
    );
}

Я поднял make_unique со страницы Herbs по этому вопросу, он включен в С++ 14 или просто использует эту версию.

http://herbsutter.com/gotw/_102/

К сожалению, мы не можем использовать вывод типа, поэтому мы должны предоставлять типы вручную.

  • 3
    OP хочет перемещать, а не копировать - поэтому может быть преобразован с помощью [](std::string& s){return make_unique<std::string>(std::move(s));}
  • 1
    О, и он хочет, чтобы это было в одной строке - так что смешайте весь вызов std::transform в одну огромную строку;)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню