3
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。

4

4 回答 4

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,仿函数可以是 just 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));
于 2013-10-24T12:45:11.173 回答
4

使用std::transform. 这负责在一行中进行实际复制。不过,您将不得不编写一个转换函数。

于 2013-10-24T12:38:50.600 回答
4

如果你添加一个getName()函数到Node,你可以这样做:

std::transform(nodes.begin(), nodes.end(), back_inserter(names), mem_fun(&Node::getName));
于 2013-10-24T12:48:31.130 回答
2

既然你提到了提升,这里有一个衬里boost::lambda

std::transform(nodes.begin(),nodes.end(), std::back_inserter(names), &boost::lambda::_1 ->* &Node::name );

Boost lambda 不能重载.*,所以首先我们需要获取地址&,然后使用->*来获取对成员的引用。

于 2013-10-24T13:08:45.587 回答