Определение количества заданных шаблонных параметров
От: Юрий Жмеренецкий ICQ 380412032
Дата: 22.10.05 02:44
Оценка: 28 (2)
Имеется шаблон с параметрами по умолчанию, например:

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


Из минусов — поменялся тип параметра.
Re: Определение количества заданных шаблонных параметров
От: _nn_ www.nemerleweb.com
Дата: 22.10.05 08:06
Оценка: +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Имеется шаблон с параметрами по умолчанию, например:


ЮЖ>
ЮЖ>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 }
};
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.