Имеется шаблон с параметрами по умолчанию, например:
struct na;
template<
class t0=na
,class t1=na
,class t2=na
,class t3=na
,class t4=na
>
struct holder
{
{enum real_arg_count = ??? }; // как определить количество реально заданных параметров ?
};
Как вариант, что-то вроде meta_if на каждый параметр.
Громоздко и трудно модифицировать.
В связи с этим родился такой вариант:
template<class t=void> struct inc {
enum {value = 1};
};
template<class t> struct inc<inc<t> > {
enum {value = inc<t>::value + 1};
};
template<
class t0=inc<>
,class t1=inc<t0>
,class t2=inc<t1>
,class t3=inc<t2>
,class t4=inc<t3>
>
struct A
{
enum {real_arg_count= 6-inc<t4>::value}; // 6=1+кол-во параметров(5), t4 - последний параметр
};
...
std::cout << A<int, char, float, double, long>::real_arg_count << std::endl; // 5
std::cout << A<int, char, float>::real_arg_count << std::endl; // 3
std::cout << A<>::real_arg_count << std::endl; // 0
Из минусов — поменялся тип параметра.
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Имеется шаблон с параметрами по умолчанию, например:
ЮЖ>ЮЖ>struct na;
ЮЖ>template<
ЮЖ> class t0=na
ЮЖ> ,class t1=na
ЮЖ> ,class t2=na
ЮЖ> ,class t3=na
ЮЖ> ,class t4=na
>>
ЮЖ>struct holder
ЮЖ>{
ЮЖ> {enum real_arg_count = ??? }; // как определить количество реально заданных параметров ?
ЮЖ>};
ЮЖ>
ЮЖ>Как вариант, что-то вроде meta_if на каждый параметр.
ЮЖ>Громоздко и трудно модифицировать.
ЮЖ>В связи с этим родился такой вариант:
ЮЖ>ЮЖ>template<class t=void> struct inc {
ЮЖ> enum {value = 1};
ЮЖ>};
ЮЖ>template<class t> struct inc<inc<t> > {
ЮЖ> enum {value = inc<t>::value + 1};
ЮЖ>};
ЮЖ>template<
ЮЖ> class t0=inc<>
ЮЖ> ,class t1=inc<t0>
ЮЖ> ,class t2=inc<t1>
ЮЖ> ,class t3=inc<t2>
ЮЖ> ,class t4=inc<t3>
>>
ЮЖ>struct A
ЮЖ>{
ЮЖ> enum {real_arg_count= 6-inc<t4>::value}; // 6=1+кол-во параметров(5), t4 - последний параметр
ЮЖ>};
ЮЖ>...
ЮЖ>std::cout << A<int, char, float, double, long>::real_arg_count << std::endl; // 5
ЮЖ>std::cout << A<int, char, float>::real_arg_count << std::endl; // 3
ЮЖ>std::cout << A<>::real_arg_count << std::endl; // 0
ЮЖ>
ЮЖ>Из минусов — поменялся тип параметра.
Можете посмотреть реализацию boost::tuple.
Там сделали переходник с класса tuple, у которого как у вас много аргументов, на класс cons, который выглядит :
template<typename Head, typename Tail>
struct cons
{
Head head;
Tail tail;
typedef Head head_type;
typedef Tail tail_type;
//...
};
В общих чертах получается из tuple<int, char, long, short> что-то вроде cons<int, cons<char, cons<long, cons<short, null_type> > > >.
А когда уже есть рекурсивный класс подсчитать количество аргументов не проблема:
template<class T>
struct length {
enum { value = 1 + length<typename T::tail_type>::value };
};
template<>
struct length<null_type> {
enum { value = 0 }
};