简体   繁体   中英

convert array of variants to std::tuple

I am working on a C++11 wrapper for a variant type implemented in C. The variant type supports common data types like int, float, string, but also tuples . I have converters for the basic types of the form...

template<typename T>
T convert_to(const Variant &var);

... but I am struggling with conversion to std::tuple.

The underlying C API can break out a tuple by returning an array of Variants. It looks something like this:

int get_tuple(Variant var, Variant **argv, int *argc);

Now I recognize I can manually create templates for each size of tuple, but I am looking for a variadic solution that can handle any size of tuple. Any tips on how to approach this?

BTW, the actual thing that I'm trying to wrap is the Erlang NIF API.

Since you're using C++11 (and you know the tuple type from the template parameter), you can happily use variadic templates. Something like*

template <class ... Ts>
std::tuple<Ts...> convert_to(const Variant& v)
{
  Variant tmp_array[std::tuple_size<std::tuple<Ts...>>::value];
  get_tuple(v, tmp_array, sizeof(tmp_array)/sizeof(tmp_array[0]));
  std::tuple<Ts...> ret;
  array_to_tuple(ret, tmp_array);
  return ret;
}

where array_to_tuple will copy the elements one by one:

template <class ... Ts>
struct array_to_tupler
{
  template <int I>
  static void do_it(std::tuple<Ts...> &t, Variant* vs)
  {
    std::get<I-1>(t) = convert_to<decltype(std::get<I-1>(t))>(vs[I-1]);
    do_it<I-1>(t, vs);
  }
  template <>
  static void do_it<0>(std::tuple<Ts...> &t, Variant* vs)
  {
  }
};

template <int N, class ... Ts>
void array_to_tuple(std::tuple<Ts...> &t, Variant (&vs)[N])
{
  array_to_tupler<Ts...>::do_it<N>(t, vs);
}

Hope this can work...

*) Note that such convert_to will not be easily callable. I suggest doing the specialization on the return types with class templates, because you need partial specialization, which function template cannot have.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM