我想实现一个排序指针向量,如下面的
#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;
};
如何实现添加功能?非常感谢。
答案 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
不是可复制的,但它是可移动的。