Вариации на тему STL. Адаптер обобщенного указателя на функцию-член класса - страница 3

Шрифт
Интервал

стр.

> };

>};


>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);

>}

Заключение

Надеюсь, читатель понял, что создание адаптера как такового не было основной целью этой статьи, тем более что гораздо более общий вариант такого адаптера под названием bind находится в библиотеке boost. Основная задача, которая стояла передо мной, была такова: дать читателю некоторые навыки и умения, позволяющие не пасовать перед необходимостью внести какие-либо дополнения или изменения в STL, а также познакомить с некоторыми приемами, специфичными для C++ и полезными при необходимости работать с компиляторами, не вполне поддерживающими стандарты.

Я благодарю Павла Кузнецова и Андрея Тарасевича за плодотворную дискуссию в форуме, непосредственно предшествовавшую написанию этой статьи и давшую мне некоторые приемы и идеи, которые были освещены выше.



стр.

Похожие книги