将变量数组转换为 std::tuple

Posted

技术标签:

【中文标题】将变量数组转换为 std::tuple【英文标题】:convert array of variants to std::tuple 【发布时间】:2012-02-29 18:47:05 【问题描述】:

我正在为用 C 实现的变体类型开发 C++11 包装器。变体类型支持常见的数据类型,如 int、float、string,但也支持 元组。我有表单基本类型的转换器...

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

...但我正在努力转换为 std::tuple。

底层的 C API 可以通过返回一个变体数组来分解一个元组。它看起来像这样:

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

现在我认识到我可以为每种大小的元组手动创建模板,但我正在寻找一种可以处理任何大小的元组的可变参数解决方案。有关如何解决此问题的任何提示?

顺便说一句,我要包装的实际是 Erlang NIF API。

【问题讨论】:

元组的这个概念是否容易映射到std::tuple?似乎它的 arity 在运行时可用,而不是在编译时可用。如果可能的 arities 数量已知且很小,您可以通过类型擦除来摆脱这种情况,但该类型的最终界面不会像 std::tuple 那样。 如果 Variant tuple arity 与 std::tuple arity 不匹配,我打算抛出异常。 【参考方案1】:

由于您使用的是 C++11(并且您从模板参数中知道元组类型),因此您可以愉快地使用可变参数模板。像*

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;

其中array_to_tuple 会一一复制元素:

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

希望这可以工作......

*) 请注意,这样的convert_to 不容易调用。我建议使用类模板对返回类型进行特化,因为您需要部分特化,而函数模板不能。

【讨论】:

在模板类中进行函数特化是非法的,但如果将其从内到外翻转(array_to_tupler 在 int N 上模板化,do_it 在 Ts 上模板化...),则它是非法的。非常感谢您为我指明了正确的方向。

以上是关于将变量数组转换为 std::tuple的主要内容,如果未能解决你的问题,请参考以下文章

将 __m128i 值转换为 std::tuple

将 std::vector<std::tuple<>> 转换为 torch::Tensor 的最有效方法是啥?

在std :: tuple中转换元素

自动将字符串转换为数组中的变量

如何将变量转换为数组

如何将变量转换为数组