У меня есть что-то, что я хочу сделать, что очень похоже на фрагмент кода на 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 в одной строке?
Да, если вы используете функцию 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/
К сожалению, мы не можем использовать вывод типа, поэтому мы должны предоставлять типы вручную.
[](std::string& s){return make_unique<std::string>(std::move(s));}
std::transform
в одну огромную строку;)