2013-01-31 55 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