|
||||
|
Проблемы с интерфейсом mem_fun_t Реализация gen_mem_fun Обобщение mem_funПроблемы с интерфейсом mem_fun_t Для начала обратим внимание на то, что mem_fun_t::operator() принимает только указатель на объект класса, чьим членом является функция pm. От этого было бы неплохо избавиться. Рассмотрим такой вариант: template<class TT, class R, class T> struct gen_mem_fun_t { explicit gen_mem_fun_t(R (T::*pm)()); R operator()(TT p); }; Сразу видна пара недостатков – во-первых, теперь адаптер может работать только с одним типом обобщенных указателей, а во-вторых, этот тип придется задавать при создании адаптера. Эти соображения должны натолкнуть нас на мысль воспользоваться шаблонными функциями-членами классов. template<class R, class T> struct gen_mem_fun_t { explicit gen_mem_fun_t(R (T::*pm)()); template<class TT> R operator()(TT p); }; Теперь все хорошо – при необходимости вызвать operator() для специфичного обобщенного указателя сгенерируется своя функция operator(). Реализация gen_mem_fun_tРассмотрим реализацию mem_fun_t: template<class R, class T> struct mem_fun_t { explicit mem_fun_t(R (T::*pm_)()): pm(pm_){} R operator()(T *p) const {return ((p->*pm)());} private: R (T::*pm)(); }; Все кажется идеальным для работы с указателями, но ведь обобщенный указатель – это не указатель, он не знает, что такое operator->*! Нужно явно узнать, на какой объект он ссылается и потом уже выполнять операцию ->* 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 (p.operator->()->*pm)();} private: R (T::*pm)(); }; Правда, возникает другая одна проблема – если теперь мы захотим использовать наш адаптер с обычным указателем, то потерпим поражение: обычные указатели не понимают operator->(). Таким образом, нам необходимо специализировать нашу функцию operator() для работы с обычными указателями: template<> R operator()(T* p) { return (p->*pm)(); } Реализация gen_mem_fun Теперь реализация gen_mem_fun становится тривиальной: template<class R, class T> gen_mem_fun_t<R, T> gen_mem_fun(R (T::*pm)()) { return gen_mem_fun_t<R, T>(pm); } |
|
||
Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх |
||||
|