从对象列表中提取某个成员的优雅方式

时间:2018-03-16 13:36:27

标签: c++

我有一个容器,其中包含一些任意结构/类的元素。 是否有一种优雅的方法可以将单个属性(例如member或member.function)提取到一个自己的数组中(例如将其传递给另一个算法)?

#include <iostream>
#include <string>
#include <vector>

int main()
{
    struct A{
      int n;
      int B()const;
    };

    std::vector<A>   manyOfA{{1,1}, {2,2},{3,3}};
    std::vector<int> allNs;

    // is there a standard way to do this kind of extraction?
    for(const auto& a:manyOfA){
      allNs.push_back(a.n);
      // or maybe allNs.push_back(a.B());
    };

    std::cout << "result Vector: ";
    for(const auto& n: allNs){
      std::cout << n << ", ";
    };
    std::cout << std::endl;
}

2 个答案:

答案 0 :(得分:3)

您可以使用std::transform将函数应用于迭代器范围的每个元素,并在结果范围内收集结果。在您的情况下,结果范围可以是std::back_inserter迭代器。这是一个特殊的迭代器,在赋值时调用给定容器上的v.push_back

std::vector<A>   manyOfA{{1,1}, {2,2},{3,3}};
std::vector<int> allNs;

std::transform(manyOfA.begin(), manyOfA.end(), std::back_inserter(allNs), [](A const& a) {return a.n;});

甚至更好的范围库,例如boost.range。这将保存新向量的创建,只是为了保存a.n

的值
template <typename RangeType>
void doSomethingWithRange(const RangeType &range) { ... }

auto allNs = manyOfA | transformed([](A const& a) {return a.n;});
doSomethingWithRange(allNs);

答案 1 :(得分:1)

此外,您还可以使用for_each

for_each(begin(manyOfA), end(manyOfA), [&](auto a) { allNs.emplace_back(a.n); });