终止函数模板递归
terminating function template recursion
我正在尝试为元组创建打印方法。我检查了其他人指定的解决方案,所有这些都使用了一个helper结构。我不想使用helper结构。我觉得下面的代码是有效的,但不能使它正确。
#include <iostream>
#include <tr1/tuple>
template<typename tupletype,size_t i>
void print< tupletype ,0>(tupletype t)//error: expected initializer before ‘<’ token
{
std::cout<<std::tr1::get<0><<" ";
}
template<typename tupletype,size_t i>
void print(tupletype t)
{
std::cout<<std::tr1::get<i><<" ";// no match for 'operator<<' in 'std::cout << get<-78ul>'(my ide actually hangs here!)
print<tupletype,i-1>(t);
}
int main (int argc, char * const argv[]) {
std::tr1::tuple<int,float> a(3,5);
typedef std::tr1::tuple<int,float> tupletype;
print<tupletype,0>(a);
}
这里有一个没有特定帮助结构的:
#include <iostream>
#include <tuple>
template<std::size_t> struct int2type{};
template<class Tuple, std::size_t I>
void print_imp(Tuple const& t, int2type<I>){
print_imp(t, int2type<I-1>());
std::cout << ' ' << std::get<I>(t);
}
template<class Tuple>
void print_imp(Tuple const& t, int2type<0>){
std::cout << std::get<0>(t);
}
template<class Tuple>
void print(Tuple const& t){
static std::size_t const size = std::tuple_size<Tuple>::value;
print_imp(t, int2type<size-1>());
}
Ideone上的实例。
首先,您需要声明函数模板,然后才能对其进行专门化:
template<typename tupletype,size_t i>
void print(tupletype t);
然而,它仍然不起作用,因为你不能部分专门化函数模板——而你试图做的是部分专门化。
因此,做你想做的事情的唯一方法是依靠类模板部分专业化:
template<typename tupletype,size_t i>
struct printer;
template<typename tupletype>
struct printer< tupletype ,0> {
static void print(tupletype t)
{
std::cout<<std::tr1::get<0>(t)<<" ";
}
};
template<typename tupletype,size_t i>
struct printer {
static void print(tupletype t)
{
std::cout<<std::tr1::get<i>(t)<<" ";
printer<tupletype,i-1>::print(t);
}
};
template<typename tupletype,size_t i>
void print(tupletype t)
{
printer<tupletype,i>::print(t);
}
你为什么不想那样做?
此代码无效。你不能部分专门化函数模板,这是你想要做的事情所必需的。你真的需要一个helper结构。
您有几个问题。
首先,您需要在专门化之前声明模板。
对于另一个,您忘记将元组类型实例传递给::get
然而,最大的问题是,你试图部分专门化一个函数模板,这是标准不允许的(搜索SO或谷歌了解原因)。
现在(在某种程度上)解决您的要求:
请注意,要创建通常有用的编译时递归,您需要对输入对象(即:您的元组类型)和索引进行模板化,该索引将用于递归迭代输入中的元素。模板递归需要部分专门化来定义退出条件。不能用函数模板来实现,但可以用类来实现——因此,使用结构。
现在,在特定的意义上,您实际上可以在不使用structs的情况下实现您想要的。要做到这一点,您需要避免部分专业化。。。因此,我们需要完全专业化。(在我投票之前,我完全承认这个解决方案在一般意义上不是很有用,但OP希望避免结构化,所以我做到了!)
通过使函数只采用特定的元组类型,我们只能有一个模板参数-索引。因此,我们可以完全专门化函数模板,以获得退出条件:
#include <iostream>
#include <tr1/tuple>
typedef std::tr1::tuple<int,float> tupletype;
template<size_t i>
void print(tupletype t)
{
std::cout << std::tr1::get<i>(t) << " ";
print<i-1>(t);
}
template<>
void print<0>(tupletype t)
{
std::cout << std::tr1::get<0>(t) << " ";
}
int main()
{
tupletype a(3,5);
print<1>(a);
}
相关文章:
- 递归函数计算序列中的平方和(并输出过程)
- 如何在Elixir中调用递归函数并行
- 递归函数有效,但无法记忆
- 为什么我的递归函数按降序打印,然后按升序打印?
- 为什么递归函数的最终输出是 5?
- 作用于可变类模板参数的递归函数
- 为模板中的元组创建递归函数
- 我如何实现递归函数的模板,该模板允许C 中的许多不确定数据类型的参数
- 使用条件运算符递归计算模板化值或函数时出现错误 C1202(堆栈溢出)
- 递归调用模板化函数 (C++)
- 具有函数模板的递归函数
- 在其静态递归函数中展开结构类型模板参数包
- 我的二进制搜索树 c++ 的递归函数中的错误 C2784 无法推断模板参数
- 模板作为递归函数工作
- 递归调用模板类的成员函数
- 模板化递归函数的语法是什么
- 用新的模板参数递归调用模板化函数
- c++中重载递归函数的模板推导规则
- 如何编写可变模板递归函数
- 更改类型后递归为模板化函数