C++ 如果向量包含变量,则删除_

C++ 如果向量包含变量,则删除_,c++,c++17,variant,C++,C++17,Variant,我有两个不同的目标: 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; }; 它们存储在带有std::variant std::vector<std::variant&

我有两个不同的目标:

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;
};
它们存储在带有
std::variant

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

但是如何合并
std::variant
?我试图用
std::visit
想出一些东西,但是我不能在
std::remove\u的谓词中添加它,如果
或者我可以吗?

是的,
std::visit
可以帮助。传递给
visit
的functor只需要能够接受每种类型的
变量
,最简单的方法是使用通用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());
在这里,外部lambda的
v
类型始终用作
const std::variant&
,并且
auto
比键入
std::variant
更方便。但是对于内部lambda,lambda是泛型的很重要,因为
visit
将使用
TypeA
TypeB
实例化其模板
operator()
,如果要访问不同类型的“相同”数据成员,然后,这些类型需要是定义此数据成员的公共多态基类的子类

但是,在您的情况下,如果
TypeA
TypeB
不相关,则必须对相应的数据成员进行类型安全访问。@aschepler提供的解决方案使用
std::visit
functor以通用方式显示了这一点;以下解决方案没有
std::visit
(因此没有那么优雅,但仍然有效):

ab.erase(std::remove_if(ab.begin(),ab.end(),
[](const std::variant&v){
国际贸易编号;
如果(v.index()==0){
否=标准::获取(v)。否;
}否则{
否=标准::获取(v)。否;
}
返回no==0;
}),ab.end());

这只是自找麻烦。将第三种类型添加到变体时会发生什么?你还记得你需要更新这个吗?如果你要找的类型复制起来不便宜怎么办?还是完全可以复制?还是默认可构造?
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());
ab.erase(std::remove_if(ab.begin(), ab.end(),
    [](const std::variant< TypeA, TypeB>& v) { 
      int no;
      if (v.index()==0) {
         no = std::get<0>(v).no;
      } else {
         no = std::get<1>(v).no;
      }
      return no==0;
    }), ab.end());