C ++ decltype,带有if语句,用于递归函数

时间:2014-05-08 10:54:55

标签: c++ templates c++11 recursion decltype

我正试图递归遍历我的模板结构。
为此,我编写了递归函数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++);

我真的不明白为什么。它似乎试图进一步遍历它应该。

2 个答案:

答案 0 :(得分:3)

即使编译器知道无法输入else块,其中的代码也必须在语法上有效。当pdouble时,请考虑此处发生的事情:

if (current == i){
    return p.el0;
} else {
    return get_my(p.el1, i, current++);
}

get_my被实例化,在其中,编译器看到return p.e10 Pairdouble

解决方案正在超载。编写my_get的另一个重载,当Pair推导出除my_pair以外的其他内容时,它会停止递归。例如,可以使用enable_if idiom来完成此操作。

更好的是,你可以使用递归my_pair<T1, T2>的重载,以及另一种不递归的通用模板。不需要enable_if

答案 1 :(得分:1)

您尝试根据问题current == i ? type1 : type2指定退货类型。

返回类型应该在编译时知道。在您的情况下decltype正在返回double作为类型,那么您正在尝试调用该基本类型的.el0方法。