问题
I have a std::list<obj*>, where obj is my class:
std::list<obj*> list_of_ptr;
list_of_ptr.push_back(new obj());
I want to convert this list to the equivalent std::list<obj>, after that I no longer need the list_of_ptr.
What is the fastest way to do this work?
回答1:
std::transform is your friend:
std::vector<obj> objects;
std::transform(
list_of_ptr.begin(), list_of_ptr.end(),
std::back_inserter(objects),
[](obj* p) { return *p; });
Or, if C++11 lambda expressions cannot be used, one may use a simple function object to perform the indirection:
struct indirect
{
template <typename T>
T& operator()(T* p) { return *p; }
};
std::transform(
list_of_ptr.begin(), list_of_ptr.end(),
std::back_inserter(objects),
indirect());
Or, using boost::indirect_iterator:
std::vector<obj> objects(
boost::make_indirect_iterator(list_of_ptr.begin()),
boost::make_indirect_iterator(list_of_ptr.end()));
These, of course, assume that there are no null pointers in the sequence. It is left as an exercise for the reader to figure out how to correctly manage the lifetimes of the objects pointed to by the pointers in list_of_ptr.
Ideally, one would use a std::vector<obj> from the start, or, if that is not possible, a container of smart pointers. Manually managing the lifetimes of the pointed-to objects, and doing so correctly, is very difficult. C++ has awesome automatic object lifetime management facilities (destructors, smart pointers, containers, stack semantics, RAII), and there is no reason not to use them.
回答2:
Simplicity and code that is easy to understand is also your friend:
for each (obj* pObj in list_of_ptr)
{
if (pObj != nullptr)
{
list_of_objects.push_back(*pObj);
}
}
And if that doesn't compile for you, this certainly should:
std::list<obj> list_of_objects;
for_each(list_of_ptr.begin(), list_of_ptr.end(), [&list_of_objects] (obj* pObj) {
if (pObj != nullptr)
list_of_objects.push_back(*pObj);
});
来源:https://stackoverflow.com/questions/11335457/fast-way-to-convert-stdlist-of-pointer-to-stdlist-of-value