Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Упростить макрос


Автор: ИванМ 18.10.2010, 01:16
Есть такие макросы:
Код

#define HANDLER_1(Name_, Func_)\
    void Name_(Func_);    \
    template<typename Object, typename Function>\
    void Name_(Object& obj, Function func)\
    {\
        Name_(boost::bind(func, &obj, _1));\
    }
//........
#define HANDLER_4(Name_, Func_)\
    void Name_(Func_);    \
    template<typename Object, typename Function>\
    void Name_(Object& obj, Function func)\
    {\
        Name_(boost::bind(func, &obj, _1, _2, _3, _4));\
    }

Они отличаются друг от друга только количеством параметров в bind.
Можно ли как-то упростить задачу, чтобы писать не несколько похожих макросов, а только один?

Автор: boostcoder 18.10.2010, 01:34
Цитата(ИванМ @  18.10.2010,  01:16 Найти цитируемый пост)
_1, _2, _3, _4

вместо этого, вам нужно использовать макрос-перечислитель: http://www.boost.org/doc/libs/1_44_0/libs/preprocessor/doc/ref/enum_shifted_params.html и в HANDLER передавать дополнительный числовой аргумент.

должно получиться что-то вроде этого:
Код

#define HANDLER(Name_, Func_, N_)\
    void Name_(Func_);    \
    template<typename Object, typename Function>\
    void Name_(Object& obj, Function func)\
    {\
        Name_(boost::bind(func, &obj, BOOST_PP_ENUM_SHIFTED_PARAMS(N_, _)));\
    }

Автор: ИванМ 18.10.2010, 03:30
boostcoder, ваш код не работает. Как я понимаю, заполняется данными '_' , а надо _1, _2...

Автор: boostcoder 18.10.2010, 07:46
у меня все корректно препроцессируется.
возможно вы забыли заинклудить <boost/preprocessor/repetition/enum_shifted_params.hpp>

Добавлено @ 07:54
конечный вариант:
Код

#define HANDLER(Name_, Func_, N_)\
   void Name_(Func_);    \
   template<typename Object, typename Function>\
   void Name_(Object& obj, Function func)\
   {\
      Name_(boost::bind(func, &obj, BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ADD(N_, 1), _)));\
   }



декларация:
Код

HANDLER(testfunc, bodyfunc, 4)


результат:
Код

void testfunc(bodyfunc);
template<typename Object, typename Function> void testfunc(Object& obj, Function func)
{
   testfunc(boost::bind(func, &obj, _1 , _2 , _3 , _4));
}


Автор: cupper 18.10.2010, 09:18
http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variadic-Macros.html#Variadic-Macros

Автор: boostcoder 18.10.2010, 09:28
Цитата(cupper @ 18.10.2010,  09:18)
http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variadic-Macros.html#Variadic-Macros

хорошо.
покажите способ, решить поставленную ТС`ом задачу, используя приведенную вами ссылку smile 

Автор: cupper 18.10.2010, 11:16
Код

#include <stdio.h>

#define test(func, arg...) func(arg)

int func(int i) {printf("%d\n", i);}
int func(int i, int j) {printf("%d, %d\n", i, j);}

int main()
{
    test(func, 1);
    test(func, 2, 3);
}

Но это конечно если не лень ручками перечислять наборы параметров. 

Автор: boostcoder 18.10.2010, 11:18
cupper, вы наверное первый пост не прочитали.

Автор: cupper 18.10.2010, 11:32
уже несколько раз перечитал. Но так и непонял откуда берутся параметры _1, _2, _3 smile
Если имена у них однотипные как и тут, то да буст сдесь лучше. А если они не обязательно имеют одинаковый формат имени? Но наверно сдесь всетаки первый вариант.

Автор: boostcoder 18.10.2010, 11:44
Цитата(cupper @  18.10.2010,  11:32 Найти цитируемый пост)
так и непонял откуда берутся параметры _1, _2, _3

это плейсхолдеры.


Цитата(cupper @  18.10.2010,  11:32 Найти цитируемый пост)
А если они не обязательно имеют одинаковый формат имени?

обязательно.

Автор: ИванМ 18.10.2010, 14:22
boostcoder, вот теперь работает. Спасибо, плюс в репу.

Автор: boostcoder 18.10.2010, 14:23
ИванМ, тему закрой.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)