以递归方式构建一个元组
给定一个参数包和一个字符串向量,我想递归地构建一个元组,并且每次都取第一个元组,并将其附加到元组中。所以如果我有一个带有“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)
您应该从非最终版本的返回值的tuple_maker
:
return tuple_maker(newtup2, vec, args...);
而且从最后一个:
return t;
这样,各种实例化调用链tuple_maker
变成了一串尾调用,最后一个返回累计值。
我试过,但我只是不知道该怎么做。我为它尝试了一个可变模板,但那不起作用 – user2770808
“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
产生的类型,并将其递归结果应用于元组的其余部分。
如果您使用的是C++ 14,那么'auto'应该就足够了......如果不是,您可以尝试将'auto'与' - > decltype()'结合在一起,在decltype的括号中您应该通过调用生成元组的函数... –
你可以使函数返回类型auto ?,编辑我一直在使用C++ 11,但我会尝试14 – user2770808
是的,它应该被接受,因为编译器可以推导出结果从返回声明... –