我正在尝试为元组创建打印方法。我检查了其他人指定的解决方案,都使用了辅助结构。我不想使用helper struct。我觉得以下代码是有效的,但不能直接得到它。
#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);
}
答案 0 :(得分:14)
这是没有特定帮助器结构的那个:
#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>());
}
答案 1 :(得分:13)
首先,在专门化之前,您需要 声明功能模板 :
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);
}
你为什么不想这样做?
答案 2 :(得分:1)
此代码无效。您不能部分专门化功能模板,这是您想要做的事情所必需的。你真的需要一个辅助结构。
答案 3 :(得分:0)
你有几个问题。
您需要在专门化之前声明模板。
对于另一个,您忘记将tupletype实例传递给:: get
然而,最大的一点是你试图部分专门化一个功能模板,这是标准不允许的(搜索SO或谷歌详细阐述原因)。
现在解决(有点)你要求的问题:
注意,要创建通常有用的编译时递归,您需要模拟输入对象(即:您的元组类型)和一个索引,该索引将用于递归迭代输入中的元素。模板递归需要部分特化来定义退出条件。您无法使用函数模板执行此操作,但您可以使用类来执行此操作 - 因此,请使用结构。
现在,在特定的意义上,您实际上可以在不使用结构的情况下实现您想要的效果。要做到这一点,你需要避免部分专业化......因此我们需要完全专业化。 (在我投票之前 - 我完全承认这个解决方案在一般意义上不是很有用 - 但是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);
}