C++11,仅将一个字段复制到向量中

C++11, copying just one field into a vector

本文关键字:字段 一个 复制 向量 C++11      更新时间:2023-10-16

假设我在C++中有以下结构

struct Foo {
double a;
int b;
};

假设我有一个参数来声明如下的某个函数:

const std::initializer_list<Foo> &args;

有没有一种简洁的方法可以从args中的元素中提取一个字段,例如,仅获得一个包含原始args列表中每个b字段的 std::vector?

当然,我知道我可以通过明确地将其写成循环来做到这一点:

std::vector<int> result;
for(auto &x:args) {
result.push_back(x.b);
}

。但鉴于我可以将任何类型的整个initializer_list复制到一行C++中的类似类型向量,只需使用 std::copy 和 std::back_inserter 等函数,我想知道是否有更优雅的方法也可以做到这一点,使用 stl 或可能已经存在的 C++11 设施。

您可以使用std::transform并通过std::back_inserter将元素添加到向量中:

std::transform(std::begin(args), std::end(args), std::back_inserter(result), 
[] (const Foo & foo) { return foo.b; });

如果您发现 lambda 太冗长,则可以改用std::mem_fn(功劳归于 @StoryTeller)。

std::transform(std::begin(args), std::end(args), std::back_inserter(result), std::mem_fn(&Foo::b));

但话又说回来,你的方法不一定是坏的,因为它非常可读并且做得很好(可能会有一些性能问题)。

一种解决方案可以是使用 linq++,如下所示:

shared_ptr<vector<Foo>> foo_list; 
// suppose foo_list is being filled
shared_ptr<vector> bs = from(foo_list).select(&_1 ->* &Foo::b).get();
相关文章: