如何实现排序指针向量?

时间:2012-12-29 18:30:44

标签: c++ containers

我想实现一个排序指针向量,如下面的

#include <vector>
#include <memory>
#include <algorithm>

//! A random accessed vector with sorted allocated elements.
//! - Elements must be allocated on heap.
//! - The vector manages the memories of its elements.
template<class T, class Compare = std::less<T>>
class SortedPtrVector
{
public:
    SortedPtrVector()   {}

    //! Add an element, return its index.
    int Add(T* element)
    {
        auto position = std::lower_bound(m_vector.begin(), m_vector.end(), 
            element, Compare); // Wrong here due to compare smart pointers
        auto newPosition = m_vector.insert(position, element);
        return newPosition - m_vector.begin();
    }

private:
    std::vector<std::unique_ptr<T>> m_vector;
};

如何实现添加功能?非常感谢。

2 个答案:

答案 0 :(得分:1)

您可以像这样实现自己的std::less,而不是使用ptr_less

template< typename T >
class ptr_less
{
    typedef bool result_type;

    bool operator ()( T const& left, T const& right ) const
    {
        return *left < *right;
    }
};

一般实现也必须检查空指针

另一种方法是使用boost::ptr_vector代替std::vector

答案 1 :(得分:1)

auto position = std::lower_bound(m_vector.begin(), m_vector.end(), 
        element, Compare);

这显然是错误的。 Compare是一种类型,而不是一种对象。

您可以将lambda与Compare的对象一起使用。所以我认为这应该有效:

Compare cmp; 
auto comparer = [&](std::unique_ptr<T> const & a, std::unique_ptr<T> const & b)
                {
                   return cmp(*a, *b); //use cmp here!
                };

std::unique_ptr<T> uniqElem(element); 

auto position = std::lower_bound( m_vector.begin(), 
                                  m_vector.end(), 
                                  uniqElem, //not element!!
                                  comparer);

请注意,当element期望类型为{{1}的值时,std::lower_bound的类型为element时,您无法将T*传递给std::lower_bound并且没有从std::unique_ptr<T>T*的隐式转换。此外,出于同样的原因,您无法将std::unique_ptr<T>插入向量。将element插入向量。

我建议您将参数改为uniqElem而不是unique_ptr,因为这表示当T*的对象消失时,将自动删除添加的项目范围:

SortedPtrVector

如果您使用int Add(T* element); //bad - doesn't say element will be deleted! int Add(std::unique_ptr<T> element); //good - says element will be deleted! 作为参数类型,请记下以下几点:

std::unique_ptr<T>

完全是因为v.Add(new T()); //will not work v.Add(std::unique_ptr<T>(new T()); //will work std::unique_ptr<T> item(new T()); v.Add(item); //will not work v.Add(std::move(item)); //will work 不是可复制的,但它是可移动的