问题是,如果元组不在其父级的第一个位置,为什么它不起作用。看起来它没有看到_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...);
}
答案 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)...);
}