首页 > 解决方案 > 不同类型的copy_if

问题描述

如果我知道如何提取匹配类型,是否有一种现代方式来表达从不同类型的源容器有条件地复制到目标容器的意图?

将问题作为代码示例更容易:

#include <algorithm>
#include <vector>

struct Foo {};
struct FooBar{
    bool is_valid;
    Foo foo;
};

std::vector<Foo> get_valid_foos(const std::vector<FooBar>& foobars){
    std::vector<Foo> valid_foos;
    for(const auto& fbar : foobars){
        if(fbar.is_valid)
            valid_foos.push_back(fbar.foo);
    }
    return valid_foos;
}

std::vector<Foo> get_valid_foos_modern(const std::vector<FooBar>& foobars){
    std::vector<Foo> valid_foos;
    std::copy_if(foobars.begin(), foobars.end(), std::back_inserter(valid_foos),
        [](const auto& foobar){
            return foobar.is_valid;
        });
    //?? std::copy requires input and output types to match
    return valid_foos;
}

https://godbolt.org/g/miPbfW

标签: c++c++14

解决方案


使用range-v3

std::vector<Foo> get_valid_foos(const std::vector<FooBar>& foobars) {
    return foobars
        | view::filter(&FooBar::is_valid)
        | view::transform(&FooBar::foo);
}

这很有表现力。


推荐阅读