我写了一个(坏)函数来解包tuple
。
template<class tuple_head_t, size_t... HeadIndices, class tuple_tail_t, size_t... TailIndices>
decltype(auto) concat_tuples_concat(tuple_head_t&& head, index_sequence<HeadIndices...>, tuple_tail_t&& tail, index_sequence<TailIndices...>) noexcept {
return make_tuple(get<HeadIndices>(forward<tuple_head_t>(head))..., get<TailIndices>(forward<tuple_tail_t>(tail))...);
}
template<class tuple_t, class... tuple_ts>
decltype(auto) concat_tuples(tuple_t&& t1, tuple_ts&&... ts) noexcept {
return concat_tuples_concat(
forward<tuple_t>(t1),
make_index_sequence<tuple_size<remove_reference_t<tuple_t>>::value>(),
concat_tuples(forward<tuple_ts>(ts)...),
make_index_sequence<tuple_size<decltype(concat_tuples(forward<tuple_ts>(ts)...))>::value>()
);
}
template<>
decltype(auto) concat_tuples<>() noexcept {
return make_tuple();
}
抛出编译时错误。
error: template-id ‘concat_tuples<>’ for ‘decltype(auto) sprincle::concat_tuples()’ does not match any template declaration
decltype(auto) concat_tuples<>() noexcept {
^
我觉得编译器的返回类型有问题。这两个decltype(auto)
评估为不同的类型,因此专业化不起作用。我发现有一个标准库函数可以连接元组tuple_cat
。我试着研究实现(GCC 5.2.0)以了解返回类型是如何推断出来的,但是对我来说理解起来太神秘了。
如果你碰巧知道怎么做,你介意分享吗?
答案 0 :(得分:1)
您的空案例正在尝试为不存在的模板声明提供完全专业化(声明的主模板至少需要一个参数)。而不是使空案例成为完整的模板专业化,只需将其作为一个单独的重载并在递归情况上定义它:
decltype(auto) concat_tuples() noexcept {
return make_tuple();
}
template<class tuple_t, class... tuple_ts>
decltype(auto) concat_tuples(tuple_t&& t1, tuple_ts&&... ts) noexcept {
return concat_tuples_concat(
forward<tuple_t>(t1),
make_index_sequence<tuple_size<remove_reference_t<tuple_t>>::value>(),
concat_tuples(forward<tuple_ts>(ts)...),
make_index_sequence<tuple_size<decltype(concat_tuples(forward<tuple_ts>(ts)...))>::value>()
);
}