c++ - 我可以将 auto_ptr 放入 STL 容器中吗?

标签 c++ stl auto-ptr

我继承了一个接口(interface),并实现了一个虚拟函数,该函数应该对动态分配的对象列表做一些工作。第一步是根据一些自定义等效标准从列表中删除重复项:

class Foo { /* ... */ };

struct FooLess
{
    bool operator()(const Foo *lhs, const Foo *rhs);
}

struct FooEqual
{
    bool operator()(const Foo *lhs, const Foo *rhs);
}

void doStuff(std::list<Foo*> &foos)
{
    // use the sort + unique idiom to find and erase duplicates
    FooLess less;
    FooEqual equal;
    foos.sort( foos.begin(), foos.end(), less );
    foos.erase( 
        std::unique( foos.begin(), foos.end(), equal ), 
        foos.end() ); // memory leak!
}

问题是使用sort + unique不会清理内存,要erased的元素有未指定的值在 unique 之后,所以我无法在 eraseing 之前自行执行清理。我正在考虑这样的事情:

void doStuff(std::list<Foo*> &foos)
{
    // make a temporary copy of the input as a list of auto_ptr's
    std::list<auto_ptr<Foo>> auto_foos;
    for (std::list<Foo>::iterator it = foos.begin(); it != foos.end(); ++it) 
        auto_foos.push_back(auto_ptr<Foo>(*it));
    foos.clear();

    FooLess less; // would need to change implementation to work on auto_ptr<Foo>
    FooEqual equal; // likewise
    auto_foos.sort( auto_foos.begin(), auto_foos.end(), less );
    auto_foos.erase( 
        std::unique( auto_foos.begin(), auto_foos.end(), equal ), 
        auto_foos.end() ); // okay now, duplicates deallocated

    // transfer ownership of the remaining objects back
    for (std::list<auto_ptr<Foo>>::iterator it = auto_foos.begin(); 
        it != auto_foos.end(); ++it) 
    { foos.push_back(it->get()); it->release(); }
}

这样可以吗,还是我遗漏了什么?

我无法使用 C++11(Boost 可能是可能的)或更改函数签名以接受简单的 Foo 列表。

最佳答案

要将对象放入标准容器中,对象需要值语义(标准称“可复制分配”和“可复制构造”)。除其他外,这意味着复制构造函数和赋值运算符需要创建对象的拷贝(保持原始不变)

auto_ptr 复制构造函数不会那样做。相反,复制构造函数和赋值运算符转移指针的所有权。

因此,标准容器不可能包含 auto_ptr。

许多实现(如在编译器和标准库中)都有标准容器和/或 auto_ptr 编码,因此尝试拥有 auto_ptr 的容器将触发编译器错误。不幸的是,并非所有实现都这样做。

关于c++ - 我可以将 auto_ptr 放入 STL 容器中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28364367/

相关文章:

c++ - 有什么理由使用 auto_ptr 吗?

c++ - 如何在 STL map 内迭代 STL map ?

c++ - 这是一个很好的 std::auto_ptr<> 用例吗?

c++ - 使用 std::auto_ptr 数据成员是否调用 UB?

c++ - 调用重载的构造函数会产生歧义错误 C++

c++ - 更简洁的 C++ 版本可能吗?

c++ - STL:: map 问题

c++ - 重新启动流式 OpenAL 源代码?

c++ - 如何通过全名从双向链表中删除重复项

c++ - 将任何类型转换为任何类型