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

使用する代わりに、次のよう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ポインタもチェックする必要があります。

別のアプローチは、boost::ptr_vectorの代わりに使用することですstd::vector

于 2012-12-29T18:37:04.980 に答える
1
auto position = std::lower_bound(m_vector.begin(), m_vector.end(), 
        element, Compare);

これは明らかに間違っています。Compareは型であり、オブジェクトではありません。

のオブジェクトでラムダを使用できます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の値を期待し、からへの暗黙の変換がない場合、typeのようにに渡すelementことはできないことに注意してください。また、同じ理由でベクターに挿入することはできません。ベクトルに挿入します。std::lower_boundelementT*std::lower_boundstd::unique_ptr<T>T*std::unique_ptr<T>elementuniqElem

のオブジェクトがスコープ外になると、追加されたアイテムが自動的に削除されることをユーザーに示すため、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できないからですが、移動可能です。

于 2012-12-29T18:40:35.743 に答える