如何实现排序的指针向量

How to implement sorted pointer vector?

本文关键字:排序 指针 向量 实现 何实现      更新时间:2023-10-16

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

#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;
};

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

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传递给std::lower_bound,因为elementT*类型,当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

这全是因为std::unique_ptr不是可复制,但它是可移动

而不是使用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;
    }
};

一般实施也必须检查 null Pointers

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