问题
I have an object:
class Object {
public:
boost::shared_ptr<QString> const& name() const {reutrn _name;}
private:
boost::shared_ptr<QString> _name;
};
And a multi_index set
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;
Now If I want to find something in the set and I have QString
I need to make a copy of it to allocate in heap and create shared_ptr
.
Is it possible to avoid this unnecessary copy operation, leaving the set as it is?
回答1:
A simpler way: add the following member functions to your StringPointerLess
comparison predicate:
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;
}
...
};
and now you can lookup by simply providing the desired QString
:
IteratorType find( MyContainerType const& container, QString const& key )
{
return container.find( key );
}
The magic behind this is explained at the special lookup operations section in Boost.MultiIndex documentation.
回答2:
Yes, you still have to make a shared_ptr but you can use a custom-deleter that does not delete your object, and then pass it in as a pointer from the stack.
Of course one of your issues is that your shared_pointer
is not to const
, so if you have a const QString &
you either have to duplicate it or const_cast
. I will do the latter but leave it up to you what to do.
We don't want to do that everywhere we pass in a QString so let's write a function:
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 );
}
来源:https://stackoverflow.com/questions/15228895/searching-in-a-set-of-shared-ptrqstring