2013-03-05 28 views
3

的搜索我有一個對象:在一組的shared_ptr <QString>

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

你確定你已經定義了ObjectSet嗎?通過索引'boost :: shared_ptr ',如果兩個元素的'name'成員指向相同的字符串,則認爲它們是等價的; *如果它們指向的字符串相同,則認爲它們不相等。 – 2013-03-05 18:20:50

+0

爲此我有'StringPointerLess'。 – user14416 2013-03-05 20:03:55

回答

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

是的,您仍然必須創建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); 
} 
相關問題