以递归方式构建一个元组

问题描述:

给定一个参数包和一个字符串向量,我想递归地构建一个元组,并且每次都取第一个元组,并将其附加到元组中。所以如果我有一个带有“string1”,“string2”,“string3”和一个参数包5,2.5,真的向量......结果元组将会是“string1”,5,“string2”,2.5,“string3 “,的确如此。以递归方式构建一个元组

继承人什么我试过到目前为止

在我主我做这样的事情

std::vector<std::string> string_vec; 
std::tuple<> t; 

//initalize string_vec to something 
set_up_strings(string_vec); 

//pass an empty tuple to start building with the strings and args 
tuple_maker(t, string_vec, args...); 

在我的tuple_maker递归地把每个之一。

template<typename T, typename... Args, typename... Ts> 
void tuple_maker(std::tuple<Ts...> t, std::vector<std::string> &vec, T value, Args... args) 
{ 
    auto newTup1 = tuple_append(t, vec.begin()); 
    auto newtup2 = tuple_append(newTup1, value); 
    vec.erase(vec.begin()); 

//now pass in the vector and args after removing front of each 
    tuple_maker(newtup2, vec,args...); 
} 

最终当没有更多的指定参数时,该功能将被调用(结束递归)

template<typename... Ts> 
std::tuple<Ts...> tuple_maker(std::tuple<Ts...> t, std::vector<std::string> &vec) 
{ 

int tup_size = std::tuple_size<decltype(t)>::value; 
std::cout<< "final tuple has size of " << tup_size << std::endl; 

//return t; 

} 

如果我通过类似string1-3,和3 ARGS就像我之前提到的,它打印大小为6的元组,所以我相信它正确地创建了它。但是,我很难将其返回到主函数。我不知道如何设置返回类型,以便它将最终的元组正确地返回到前一个函数,然后返回到main。

参考,助手“tuple_maker”功能,我用的是这里

template <typename NewType, typename... TupleElem> 
std::tuple<TupleElem..., NewType> tuple_append(const std::tuple<TupleElem...> &tup, const NewType &n) 
{ 
return std::tuple_cat(tup, std::make_tuple(n)); 
} 

我想这样的事情...

template<typename T, typename... Args, typename... Ts, typename... ret> 
std::tuple<ret...> tuple_maker(std::tuple<Ts...> t, std::vector<std::string> &vec, T value, Args... args) 
+0

如果您使用的是C++ 14,那么'auto'应该就足够了......如果不是,您可以尝试将'auto'与' - > decltype()'结合在一起,在decltype的括号中您应该通过调用生成元组的函数... –

+0

你可以使函数返回类型auto ?,编辑我一直在使用C++ 11,但我会尝试14 – user2770808

+0

是的,它应该被接受,因为编译器可以推导出结果从返回声明... –

您应该从非最终版本的返回值的tuple_maker

return tuple_maker(newtup2, vec, args...); 

而且从最后一个:

return t; 

这样,各种实例化调用链tuple_maker变成了一串尾调用,最后一个返回累计值。

+0

我试过,但我只是不知道该怎么做。我为它尝试了一个可变模板,但那不起作用 – user2770808

+0

“make”是什么意思?每个特定实例化的返回类型都由编译器推断出来,如果你不想枚举一个元组所构成的所有字符串对,那么当你想实例化结果对象时,你可以使用关键字'auto'。 – bipll

我可以看到一对夫妇的可能出现的问题在您的tuple_maker 定义(为什么你传递一个迭代器tuple_append?),但它 看起来你有什么你正在尝试做一个手柄,所以我会让 你自己排序。

您的问题似乎在问如何确定返回 类型应该为您的功能。有几种方法可以做 这个。

其中一个很简单,但需要大量重复的代码, 使用使用decltype的尾随返回类型。但是,由于tuple_maker函数有多行代码,所以通过其他方法可能更好。

缺席C++ 14(您可以在其中只使用auto作为返回值), 你可以为你的函数像这样创建一个类型的发电机:

#include <tuple> 
#include <type_traits> 
#include <utility> 

template <typename> 
struct RetMaker { 
    using type = std::tuple<>; 
}; 

template <typename T, typename... Rest> 
struct RetMaker<std::tuple<T, Rest...>> { 
    using rest = typename RetMaker<std::tuple<Rest...>>::type; 
    using type = decltype(std::tuple_cat(
           std::declval<std::tuple<std::string, T>>(), 
           std::declval<rest>())); 
}; 

然后你的函数的返回类型为typename RetMaker<std::tuple<Ts...>>::type

我应该注意到,还有很多其他不同的方法来实现这个目标,包括做不使用std::tuple_cat,但这是第一个弹出到我脑海中的,不需要大量额外打字的方法。 decltype/std::declval位的本质是:给我一个std::string, T元组调用std::tuple_cat产生的类型,并将其递归结果应用于元组的其余部分。