1

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

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

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

4

2 回答 2

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);

请注意,当期望 type 的值并且没有从 to 的隐式转换时,您不能像type一样传递elementto 。此外,出于同样的原因,您不能插入到向量中。插入向量。std::lower_boundelementT*std::lower_boundstd::unique_ptr<T>T*std::unique_ptr<T>elementuniqElem

我建议您使用参数 asunique_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>as 参数类型,请注意以下几点:

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不可复制,但它是可移动的。

于 2012-12-29T18:40:35.743 回答
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.

于 2012-12-29T18:37:04.980 回答