In c++ when i try to write a code that returns reverse of a type list what i wrote( a user defined template class):
template <typename ...V,typename ...D>
constexpr decltype(auto) merge(const type_list<V...>& first, const type_list<D...>& second)
{
return type_list<V...,D...>();
}
template<typename First, typename ...Var>
constexpr decltype(auto) _reverse(type_list<First,Var...> ls)
{
if constexpr (empty(ls)) return type_list<>();
return merge(_reverse(type_list<Var...>()),type_list<First>());
}
and when i try to run:
aml::type_list<int,float> ls;
auto x = aml::_reverse(ls);
clang says:
In file included from test.cpp:4:
././lesson_4.hpp:64:16: error: no matching function for call to '_reverse'
64 | return merge(_reverse(type_list<Var...>()),type_list<First>());
| ^~~~~~~~
././lesson_4.hpp:64:16: note: in instantiation of function template specialization 'aml::_reverse<float>' requested here
test.cpp:10:16: note: in instantiation of function template specialization 'aml::_reverse<int, float>' requested here
10 | auto x = aml::_reverse(ls);
| ^
././lesson_4.hpp:61:27: note: candidate template ignored: failed template argument deduction
61 | constexpr decltype(auto) _reverse(type_list<First,Var...> ls)
| ^
1 error generated.
Could you please explain me why compiler just can't instantiate for example reverse<int,int,float> function template <typename First = int, template ...Other = {int,float}>? And why it says another specialation is needed like <int,float>? because i think they are also an instance of typename First, typename ...Other specialation
_reverseaccepts atype_listwith at least one element. There's no overload that can accepttype_list<>._reverse<int,int,float>calls_reverse<int, float>which calls_reverse<float>which attempts to call_reverse<>- but_reverserequires at least one type, forFirstparameter. Hence the error.elsesomergebranch would be discarded when empty.ifand call tomerge. I think something like this makes it clearer anyway: godbolt.org/z/35abMsTTnaml::type_listso people can plug the code into their environment of choice and compile without editing anything, presumably something like this:template<typename... Ts> struct type_list { constexpr bool empty() const { return sizeof...(Ts) == 0; } };(You'll probably also want to add#include <iterator>andusing std::empty;, so theempty(ls)compiles without issue.)