R operator()(TT p, R (T::*pm)()) {return (p.operator->()->*pm)();}

};


template<class R, class T>

struct gen_mem_fun_operator<R, T, T*> {

 R operator()(T* p, R (T::*pm)()) {return (p->*pm)();}

};


Тогда наш gen_mem_fun_t запишется так:

template<class R, class T>

struct gen_mem_fun_t {

 explicit gen_mem_fun_t(R (T::*pm_)()): pm(pm_) {}

 template<class TT> R operator()(TT p) {return gen_mem_fun_operator<R, T, TT>()(p, pm);}

private:

 R (T::*pm)();

};

Проблема “return void”

Посмотрим внимательнее на реализацию функции operator() в нашем адаптере. Что будет, если мы захотим в качестве типа возвращаемого значения функции использовать void? Наша функция запишется так: void operator() {return void;}. С точки зрения стандарта все хорошо, но все в нашем мире определяется стандартом: есть компиляторы, которые не воспринимают такую конструкцию как допустимую.

ПРИМЕЧАНИЕ Таков, к примеру, Microsoft Visual C++ 6.0/7.0

К счастью, на помощь нам опять приходит частичная специализация:

template<class T, class TT>

struct gen_mem_fun_operator<void, T, TT> {

 void operator()(TT p, void (T::*pm)()) {(p.operator->()->*pm)();}

};


template<class T>

struct gen_mem_fun_operator<void, T, T*> {

 void operator()(T* p, void (T::*pm)()) {(p->*pm)();}



5 из 8