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

Can't see function-template overload from recursive call

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

内部看到元组的过载
_print(make_tuple(), 0);

对此评价:

a tuple
not a tuple

_print(0, make_tuple());

给出这个:

not a tuple
not a 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...);
}

您的问题在这里:

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)...);   
}