2013-01-31 52 views
4

我一直在試圖從地圖中填充矢量。 我知道如何以更傳統的方式做到這一點,但我試圖用STL算法(一個班輪)作爲某種訓練來實現它:)。從shared_pointers的地圖中填充矢量

起源地圖類型是:

std::map< std::string, boost::shared_ptr<Element> > 

目的載體是:

std::vector<Element> theVector; 

什麼我到目前爲止是這樣的:

std::transform(theMap.begin(), theMap.end(), 
     std::back_inserter(theVector), 
     boost::bind(&map_type::value_type::second_type::get, _1) 
     ); 

但這試圖插入向量中的指針不起作用。 我也試過這個:

using namespace boost::lambda; 
using boost::lambda::_1; 

std::transform(theMap.begin(), theMap.end(), 
     std::back_inserter(theVector), 
     boost::bind(&map_type::value_type::second_type::get, *_1) 
     ); 

但它也不工作。

編輯:

我有這個工作解決方案,但我覺得它那麼令人印象深刻:)

std::for_each(theMap.begin(), theMap.end(), 
     [&](map_type::value_type& pair) 
     { 
      theVector.push_back(*pair.second); 
     }); 

EDIT2: 我是不太舒服的東西在這裏被綁定()所以bind()解決方案是受歡迎的!

+0

Vector _owns_它是資源,所以shared_ptr也是如此,因此在不復制副本的情況下移動在這裏是沒有問題的,但我想你不一定要從shared_ptr移動到vector,而只是爲了以優雅的方式複製。 – legends2k

+0

是的,我想要一個副本 – foke

回答

1

另一種選擇可能是新for語法:

for(auto &cur_pair: the_map) { theVector.push_back(*(cur_pair.second)); } 

它至少一襯墊(有點),雖然這只是另一種方式做你std::for_each但更緊湊。

+0

我沒有想到這個;)但我使用vs 2010,我相信它不支持這種語法 – foke

+0

你是正確的,它在2012年,但不支持2010年。請參閱此鏈接的msdn參考:http://msdn.microsoft.com/en-ca/library/vstudio/hh567368.aspx它是衆所周知的作爲該列表中的「基於範圍的循環」,並確認它是在2012年,但不是2010年。 –

2

如何:

// Using std::shared_ptr and lambdas as the solution 
// you posted used C++11 lambdas. 
// 
std::map<std::string, std::shared_ptr<Element>> m 
    { 
     { "hello", std::make_shared<Element>() }, 
     { "world", std::make_shared<Element>() } 
    }; 
std::vector<Element> v; 

std::transform(m.begin(), 
       m.end(), 
       std::back_inserter(v), 
       [](decltype(*m.begin())& p) { return *p.second; }); 

http://ideone.com/ao1C50見在線演示。

+0

你打敗了我。 ;) –

+1

或多或少等同於我的for_each解決方案。我正在尋找一個bind()解決方案,我認爲這是可能的,但我可能是錯的 – foke

+0

@foke我同意,它類似於你的解決方案,但我想你知道lambda和bind都不會改變性能和多次'綁定'更具可讀性(http://stackoverflow.com/questions/1930903/bind-vs-lambda) – legends2k