我正试图递归遍历我的模板结构。
为此,我编写了递归函数get_my。它返回链式my_pair的第i个元素。
get_my 可以是元素类型,也可以是对类型。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<typename T0, typename T1>
struct my_pair{
my_pair(T0 el0, T1 el1): el0(el0), el1(el1) {}
T0 el0;
T1 el1; // may be next pair
};
///
/// ERROR occurs here!
///
template<typename PairT>
auto get_my(PairT p, int i, int current = 0) -> decltype( current == i ? p.el0 : p.el1 ){
if (current == i){
return p.el0;
} else {
return get_my(p.el1, i, current++);
}
}
template<typename T0, typename T1>
my_pair<T0, T1> make_my_pair(T0 el0, T1 el1){
return my_pair<T0, T1>(el0, el1);
}
int main()
{
my_pair<double, double> p1(12.789, 12.66);
//auto p1 = make_my_pair(12.46, 12.66);
//auto p2 = make_my_pair(p1, 12.66);
auto el = get_my(p1, 0);
cout<< el;
return 0;
}
所以... the compilers says:
main.cpp:19:18: error: request for member 'el0' in 'p', which is of non-class type 'double'
return p.el0;
^
main.cpp:21:42: error: request for member 'el1' in 'p', which is of non-class type 'double'
return get_my(p.el1, i, current++);
我真的不明白为什么。它似乎试图进一步遍历它应该。
答案 0 :(得分:3)
即使编译器知道无法输入else
块,其中的代码也必须在语法上有效。当p
为double
时,请考虑此处发生的事情:
if (current == i){
return p.el0;
} else {
return get_my(p.el1, i, current++);
}
get_my
被实例化,在其中,编译器看到return p.e10
Pair
为double
。
解决方案正在超载。编写my_get
的另一个重载,当Pair
推导出除my_pair
以外的其他内容时,它会停止递归。例如,可以使用enable_if
idiom来完成此操作。
更好的是,你可以使用递归my_pair<T1, T2>
的重载,以及另一种不递归的通用模板。不需要enable_if
。
答案 1 :(得分:1)
您尝试根据问题current == i ? type1 : type2
指定退货类型。
返回类型应该在编译时知道。在您的情况下decltype
正在返回double
作为类型,那么您正在尝试调用该基本类型的.el0
方法。