Reputation: 14994
I have something I want to do that is extremely similar to the code snippet at cppreference.com for unique_ptr. The snippet is produced below. It compiles fine.
#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';
}
What I really want is move the strings from s into a vector of unique_ptr.
so something like std::vector<std::unique_ptr<std::string>> v2(&std::make_move_iterator(s.begin()),
&std::make_move_iterator(s.end()));
but this of course does not work.
I can only get it to do what I want with this bit of code:
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';
}
Is there a way to move resources into a container of unique_ptrs in one line?
Upvotes: 0
Views: 1203
Reputation: 16148
Yes if you use a make_unique
function as Herb Sutter recommends you can do:
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&>
);
}
I have lifted make_unique
from Herbs page on the matter, it is included with C++14 or just use this version.
http://herbsutter.com/gotw/_102/
Unfortunately we can't use type deduction so we have to provide the types manually.
Upvotes: 3