快速方法将std :: list的指针转换为std :: list of value

Nic*_*ick 3 c++ containers stl

我有一个std::list<obj*>,obj我的班级在哪里:

std::list<obj*> list_of_ptr;
list_of_ptr.push_back(new obj());
Run Code Online (Sandbox Code Playgroud)

我想将此列表转换为等效std::list<obj>,之后我不再需要了list_of_ptr.

做这项工作的最快方法是什么?

Jam*_*lis 5

std::transform 是你的朋友:

std::vector<obj> objects;
std::transform(
    list_of_ptr.begin(), list_of_ptr.end(),
    std::back_inserter(objects), 
    [](obj* p) { return *p; });
Run Code Online (Sandbox Code Playgroud)

或者,如果不能使用C++ 11 lambda表达式,可以使用简单的函数对象来执行间接:

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());
Run Code Online (Sandbox Code Playgroud)

或者,使用boost::indirect_iterator:

std::vector<obj> objects(
    boost::make_indirect_iterator(list_of_ptr.begin()),
    boost::make_indirect_iterator(list_of_ptr.end()));
Run Code Online (Sandbox Code Playgroud)

当然,这些假设序列中没有空指针.它留给练习者阅读,以弄清楚如何正确管理指针所指向的对象的生命周期list_of_ptr.

理想情况下,std::vector<obj>从一开始就使用a ,或者,如果不可能,则使用智能指针的容器.手动管理指向对象的生命周期并正确地执行此操作非常困难.C++有很棒的自动对象生命周期管理工具(析构函数,智能指针,容器,堆栈语义,RAII),没有理由不使用它们.