默认在std :: variant中构造所有类型,并将它们放入std :: vector中

问题描述

我如何制作一个std::vector,其中包含std::variant中包含的所有类型的默认构造的实例?

using TaskVariant = std::variant<TypeA,TypeB,TypeC>;
std::vector<TaskVariant> variants;

// I'd like to do this in a loop
variants.push_back(TypeA());
variants.push_back(TypeB());
variants.push_back(TypeC());

解决方法

1。解决方案::您可以将变体转换为元组,然后使用C ++ 17 std :: apply

#include <variant>
#include <iostream>
#include <string>
#include <vector>
#include <tuple>

using namespace std;

template <typename... Types>
struct ToTuple;

template <typename... Types>
struct ToTuple<variant<Types...>>
{
    using type = tuple<Types...>;
};

struct TypeA {};
struct TypeB {};
struct TypeC {};

using TaskVariant = std::variant<TypeA,TypeB,TypeC>;

int main()
{
    vector<TaskVariant> vec;
    apply([&vec](auto&&... args) {(vec.push_back(args),...); },ToTuple<TaskVariant>::type{});
}

编辑:

2。解决方案::使用 make_index_sequence variant_alternative_t variant_size_v (所有C ++ 17)(谢谢)指向 variant_alternative_t @sd ,但我通过使用 make_index_sequence 而不是递归来修改了示例):

#include <variant>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct TypeA {};
struct TypeB {};
struct TypeC {};

using TaskVariant = std::variant<TypeA,TypeC>;

template <size_t... Idx>
void fill_vec(vector<TaskVariant>& vec,index_sequence<Idx...> idx)
{
    (vec.push_back(variant_alternative_t<Idx,TaskVariant>{}),...);
}

int main()
{
    vector<TaskVariant> vec;
    fill_vec(vec,make_index_sequence<variant_size_v<TaskVariant>>{});
}
,

另一个解决方案

#include <iostream>
#include <variant>
#include <vector>

struct TypeA {
  int a;
  TypeA() : a{0} {std::cout<<"A"<<std::endl;};
};

struct TypeB {
  int b;
  TypeB() : b{0} {std::cout<<"B"<<std::endl;};
};

struct TypeC {
  int c;
  TypeC() : c{0} {std::cout<<"C"<<std::endl;};
};

using TaskVariant = std::variant<TypeA,TypeC>;

template<class var,std::size_t I = 0>
void autofill(std::vector<var>& vec){
  if constexpr(I < std::variant_size_v<var>){
    vec.push_back(std::variant_alternative_t<I,var>{});
    autofill<var,I + 1>(vec);
  }
}


int main() {
  std::vector<TaskVariant> variants;

  autofill(variants);
}

编辑:完全忘记了C ++ 17中的此功能。

template<class... VA> //VA for variant alternatives
void autofill(std::vector<std::variant<VA...> >& vec) {
    (...,vec.emplace_back(VA{}));
}

https://en.cppreference.com/w/cpp/language/fold 编辑2:好像@max在大约4小时前击败了我^^

,

使用类型的模板折叠(逗号运算符)怎么样?

@Override
,

这里使用可变参数模板的示例解决方案。

#include <vector>
#include <variant>
#include <iostream>
#include <typeinfo>

struct TypeA {};
struct TypeB {};
struct TypeC {};

using TaskVariant = std::variant<TypeA,TypeC>;

template <class T>
void addValue(std::vector<TaskVariant> & v)
{
 v.push_back(T());
 std::cout << "adding " << typeid(T).name() << " default ctor\n";
}

template <class T,class V,class... Args>
void addValue(std::vector<TaskVariant> & v)
{
  addValue<T>(v);
  addValue<V,Args...>(v);
}

template <class... Args>
void addValues(std::vector<std::variant<Args...>> & v)
{
  addValue<Args...>(v);
}

int main()
{
  std::vector<TaskVariant> variants;
  addValues(variants);
}

输出为:

adding 5TypeA default ctor
adding 5TypeB default ctor
adding 5TypeC default ctor

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...