Reputation: 73
Is something like that possible:
#include <iostream>
#include <string>
template<typename T1, typename T2, typename T3, typename T4, class ...Ts>
struct third_t {
typedef typename third_t<T2,T3,T4,Ts...>::type type;
};
template<typename T1,typename T2, typename T3>
struct third_t<T1,T2,T3,void> {
typedef T3 type;
};
int main() {
third_t<int,int,std::string,unsigned>::type z = "test";
std::cout<<"string type: "<<z<<std::endl;
}
If yes, why isn't the specialized case found? I.e. it isn't even considered in the resolution.
I get the error:
main.cpp: In instantiation of 'struct third_t<int, int, std::__cxx11::basic_string<char>, unsigned int>':
main.cpp:18:46: required from here
main.cpp:7:56: error: wrong number of template arguments (3, should be at least 4)
typedef typename third_t<T2,T3,T4,Ts...>::type type;
update:
I realized that my initial false presumption led me to think that I could "overload" a class as well, which of course is nonsense. Whereas something like that can be done with function templates, that
template<typename T1,typename T2, typename T3>
struct third_t { ... };
cannot be done with class templates, if so it would have been possible to extract the third-last parameter out of the template parameters.
Upvotes: 1
Views: 70
Reputation: 66230
why isn't the specialized case found?
Because there isn't a void
in the end of the type list of
third_t<int,int,std::string,unsigned>::type z = "test";
If you try with
third_t<int,unsigned,int,std::string,void>::type z = "test";
compile.
-- EDIT --
The OP ask to get the third type using a "recorsive construction".
So I suggest the costruction of a type traits that get the n-th-type (where n
is a template parameter) of a list of types.
Something like
template <std::size_t N, typename, typename ... Ts>
struct nth_t
{ using type = typename nth_t<N-1U, Ts...>::type; };
template <typename T0, typename ... Ts>
struct nth_t<0U, T0, Ts...>
{ using type = T0; };
So the third parameter can be found using the index 2U
(as usual in C/C++, starting from 0U
) as follows
nth_t<2U, int, int, std::string, void>::type z = "test";
Upvotes: 1