Remove_if with vector containing variants

  • A+
Category:Languages

I have two different objects:

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; }; 

They are stored in a std::vector with std::variant

std::vector<std::variant< TypeA, TypeB>> ab; 

Now i want to remove all elements were the member no = 0.

Without the std::variant with the vector containing only TypeA I would do it like this:

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

But how to incorporate the std::variant ? I tried to come up with something with std::visit but i cannot ad it in the predicate of std::remove_if or can I?

 


Yes, std::visit can help. The functor passed to visit just needs to be able to accept each type of the variant, and the easiest way to do that is with a generic 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()); 

Here the type of v for the outer lambda is always used as const std::variant<TypeA, TypeB>&, and auto is just more convenient than typing out std::variant<TypeA, TypeB>. But for the inner lambda, it's important that the lambda is generic, because visit will instantiate its template operator() with both TypeA and TypeB.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: