3

我有一个对象:

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

是否可以避免这种不必要的复制操作,保持原样?

4

2 回答 2

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 文档中的特殊查找操作部分解释了这背后的魔力。

于 2013-03-06T07:00:44.547 回答
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 );
}
于 2013-03-05T16:28:54.020 回答