struct Node
{
std::string name;
...
};
typedef std::vector<Node> Nodes;
Nodes nodes;
std::vector<std::string> names;
对于节点中的每个项目,是否有一个很好的单行方式用Node :: name填充矢量名称?
这就是我目前所做的事情:
names.reserve(nodes.size());
BOOST_FOREACH(Node node, nodes)
{
names.push_back(node.name);
}
我正在使用C ++ 98,std和boost。
答案 0 :(得分:6)
对于更新的库(boost)和/或标准(C ++ 11),这更简单,但你应该能够编写一个小的仿函数:
struct ReadNodeName {
std::string const & operator()(Node const & node) const {
return node.name;
}
};
然后使用std::transform
std::transform(nodes.begin(), nodes.end(),
std::back_inserter(names),
ReadNodeName());
使用boost,函数可能只是boost::bind
,在C ++ 11中你可以使用lambda:[](Node const & node) { return node.name; };
,在C ++ 14中使用更短的lambda [](auto& n) { return n.name; }
:
std::transform(nodes.begin(), nodes.end(),
std::back_inserter(names),
[](auto & n){return n.name;});
使用boost绑定 - 注意,未经测试,我无权访问boost
std::transform(nodes.begin(), nodes.end(),
std::back_inserter(names),
boost::bind(&Node::name, _1));
答案 1 :(得分:4)
使用std::transform
。这将在一行中处理实际的复制。但是,您必须编写转换函数。
答案 2 :(得分:4)
如果您向getName()
添加Node
功能,则可以执行以下操作:
std::transform(nodes.begin(), nodes.end(), back_inserter(names), mem_fun(&Node::getName));
答案 3 :(得分:2)
由于你提到了提升,这里有一个boost::lambda
std::transform(nodes.begin(),nodes.end(), std::back_inserter(names), &boost::lambda::_1 ->* &Node::name );
Boost lambda不能超载.*
所以首先我们需要获取地址&
,然后使用->*
来获取对成员的引用。