2012-02-29 105 views
0

我正在使用C实现的变体类型的C++ 11包装器。变体类型支持像int,float,string这样的常见数据类型,但也支持元组。我有转换器的形式的基本类型...将变量数组转换为std :: tuple

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

...但我努力转换为std ::元组。

底层的C API可以通过返回一个变量数组来分离出一个元组。它看起来是这样的:

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

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

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

+3

这个元组的概念是否容易映射到'std :: tuple'?看起来它的运行时可用,而不是编译时。如果可能的数量的arities如果已知并且很小,你可以键入 - 擦除你的出路,但是该类型的最终接口看起来不像'std :: tuple'。 – 2012-02-29 19:01:45

+0

我打算抛出一个异常如果Variant元组arity不符合std ::元组元组arity。 – goertzenator 2012-02-29 20:24:50

回答

2

由于您使用的是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不会轻易调用。我建议使用类模板对返回类型进行专门化,因为您需要部分专业化,哪些功能模板不能拥有。

+0

在模板类中使用函数专用是非法的,但是如果将其从内部翻出(array_to_tupler在int N上模板化,do_it在Ts上模板化),它将起作用。非常感谢您指引我朝着正确的方向发展。 – goertzenator 2012-03-03 20:44:48