Поиск в наборе shared_ptr & lt; QString & gt;

У меня есть объект:

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,

Можно ли избежать этой ненужной операции копирования, оставив все как есть?

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.

3

Другие решения

Да, вам все еще нужно создать 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 );
}
1

По вопросам рекламы [email protected]