无法从递归调用中看到函数模板重载

时间:2015-08-10 13:01:14

标签: c++ recursion overloading function-templates

问题是,如果元组不在其父级的第一个位置,为什么它不起作用。看起来它没有看到_after_print.

内的元组重载
_print(make_tuple(), 0);

评估:

  一个元组
  不是元组

_print(0, make_tuple());

给出这个:

  

不是元组
  不是元组

template <typename _First, typename ..._Vals>
void _print(_First&& first, _Vals... _vals)
{
    cout << "not a tuple" << endl;
    _after_print(_vals...);
}

template <typename ..._List, typename ..._Vals>
void _print(tuple<_List...>&& t, _Vals... _vals)
{
    cout << "a tuple" << endl;
    _after_print(_vals...);
}

void _print() {}

template <typename ..._Vals>
void _after_print(_Vals... _vals)
{
    _print(_vals...);
}

1 个答案:

答案 0 :(得分:1)

您的问题在这里:

template <typename ..._List, typename ..._Vals>
void _print(tuple<_List...>&& t, _Vals... _vals)
//                         ^^

我假设您想要使用完美转发,但无条件地命名一个右值引用;参考折叠规则不适用于那里。简单的解决方法是将其声明为const tuple<_List...>&,但如果您想使用完美转发,则需要执行以下操作:

//trait to check if a type is a std::tuple instantiation
template <typename T>
struct is_tuple : std::false_type{};

template <typename... Ts>
struct is_tuple<std::tuple<Ts...>> : std::true_type{};

//base case
void printImpl(char) {}

//forward declaration
template <typename First, typename ...Vals>
void printImpl(char,First&& first, Vals&&... vals);

//enabled when the first is a tuple
template <typename Tuple, typename ...Vals, 
          typename std::enable_if<is_tuple<typename std::decay<Tuple>::type>::value>::type* = nullptr>
void printImpl(int, Tuple&& t, Vals&&... vals)
{
    cout << "a tuple" << endl;
    printImpl(0,std::forward<Vals>(vals)...);
}

//first is not a tuple
template <typename First, typename ...Vals>
void printImpl(char,First&& first, Vals&&... vals)
{
    cout << "not a tuple" << endl;
    printImpl(0,std::forward<Vals>(vals)...);
}

//helper to fill in the disambiguating argument
template <typename... Ts>
void print(Ts&&... ts)
{
    printImpl(0,std::forward<Ts>(ts)...);   
}