我有一个对象:
class Object {
public:
boost::shared_ptr<QString> const& name() const {reutrn _name;}
private:
boost::shared_ptr<QString> _name;
};
还有一个multi_index集
typedef
boost::multi_index_container<
Object,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
boost::multi_index::const_mem_fun<
Object,
boost::shared_ptr<QString> const&,
& Object::name>,
StringPointerLess> > >
ObjectSet;
现在如果我想在集合中找到一些东西,我有QString
我需要复制它以在堆中分配并创建shared_ptr
。
是否可以避免这种不必要的复制操作,保留原样?
答案 0 :(得分:3)
更简单的方法:将以下成员函数添加到StringPointerLess
比较谓词:
struct StringPointerLess{
...
bool operator()(boost::shared_ptr<QString> const& x,const QString& y)const{
return *x<y;
}
bool operator()(const QString& x,boost::shared_ptr<QString> const& y)const{
return x<*y;
}
...
};
现在您只需提供所需的QString
:
IteratorType find( MyContainerType const& container, QString const& key )
{
return container.find( key );
}
Boost.MultiIndex文档中的special lookup operations section解释了这背后的魔力。
答案 1 :(得分:1)
是的,您仍然需要创建shared_ptr,但是您可以使用不删除对象的自定义删除器,然后将其作为指针从堆栈中传入。
当然,您的一个问题是shared_pointer
不是const
,所以如果您有const QString &
,则必须复制它或const_cast
。我会做后者,但留给你做什么。
我们不希望在QString传递的任何地方都这样做,所以让我们写一个函数:
struct no_op_functor
{
public:
template< typename T > operator()( T* ) const
{
}
};
IteratorType find( MyContainerType const& container, QString const& key )
{
boost::shared_ptr< QString > keyShared( const_cast<QString *>(&key), no_op_functor() );
return container.find( keyShared );
}