> };
>};
>template<> struct gen_mem_fun_traits {
> template struct signature {
> typedef void_gen_mem_fun_base_t base;
> };
>};
Этот класс специализирован для специального случая функции, возвращающей void. Таким образом, хоть нам и придется ввести дополнительный класс для функций, возвращающих void, для клиента это будет выглядеть единообразно: gen_mem_fun_traits::signature::base.
Сами по себе ветви вычислений различных вариантов тривиальны:
>template
>struct gen_mem_fun_base_t {
>protected:
> gen_mem_fun_base_t(R (T::*pm_)()): pm(pm_) {}
>public:
> template R operator()(TT p) {return (p.operator->()->*pm)();}
> template<> R operator()(T* p) {return (p->*pm)();}
>private:
> R (T::*pm)();
>};
>template
>struct void_gen_mem_fun_base_t {
>protected:
> void_gen_mem_fun_base_t(void (T::*pm_)()): pm(pm_) {}
>public:
> template void operator()(TT p) {(p.operator->()->*pm)();}
> template<> void operator()(T* p) {(p->*pm)();}
>private:
> void (T::*pm)();
>};
Теперь определим сам gen_mem_fun_t:
>template
>struct gen_mem_fun_t: gen_mem_fun_traits::template signature::base {
> typedef gen_mem_fun_traits::template signature::base base_;
> explicit gen_mem_fun_t(R (T::*pm_)()): base_(pm_) {}
>};
Один момент здесь требует пояснения: typedef используется для того, чтобы компилятор понял, какому предку нужно передать в конструктор наш указатель на функцию-член.
И, наконец, gen_mem_fun вообще остался без изменений:
>template
>gen_mem_fun_t gen_mem_fun(R (T::*pm)()) {
> return gen_mem_fun_t(pm);
>}