Remove_if包含含有变体的向量

San*_*912 4 c++ variant c++17

我有两个不同的对象:

struct TypeA {
    std::size_t no;
    std::string data;
    std::string data2;
};

struct TypeB {
    std::size_t no;
    std::string data;
    std::string data2;
    std::string data3;
};
Run Code Online (Sandbox Code Playgroud)

它们存储在一个std::vectorstd::variant

std::vector<std::variant< TypeA, TypeB>> ab;
Run Code Online (Sandbox Code Playgroud)

现在我想删除所有元素是成员no = 0.

如果没有std::variant包含的向量,TypeA我会这样做:

ab.erase(std::remove_if(ab.begin(), ab.end(),
    [](const TypeA& a) { return a.no == 0; }), ab.end());
Run Code Online (Sandbox Code Playgroud)

但如何纳入std::variant?我试图想出一些东西,std::visit但我不能在谓词中添加它,std::remove_if或者我可以吗?

asc*_*ler 10

是的,std::visit可以提供帮助.传递给的函子visit只需要能够接受每种类型的函数variant,最简单的方法是使用泛型lambda:

ab.erase(
    std::remove_if(
        ab.begin(),
        ab.end(),
        [](const auto &v) {
            return std::visit(
                [](const auto &obj) { return obj.no == 0; },
                v);
    }),
    ab.end());
Run Code Online (Sandbox Code Playgroud)

这里v外部lambda 的类型总是用作const std::variant<TypeA, TypeB>&,并且auto比输入更方便std::variant<TypeA, TypeB>.但对于内部拉姆达,这一点很重要的是,拉姆达是通用的,因为visit将实例其模板operator()TypeATypeB.