Частичная специализация
Частичная специализация
К сожалению, не все компиляторы поддерживают частичную специализацию шаблонных классов.
ПРИМЕЧАНИЕ К таким относится и Microsoft Visual C++ 6.0/7.0
Для решения этой проблемы можно использовать паттерн «traits», специфичный для C++. К сожалению, он не сможет помочь в случае, когда один из параметров шаблона специализируется типом, зависящим от другого параметра шаблона, но в случае проблемы «return void» он помочь сможет.
ПРИМЕЧАНИЕ Вопрос, реально ли вообще симулировать частичную специализацию шаблонов, где специализируемый параметр шаблона зависит от неспециализируемого, на компиляторе, не поддерживающем частичную специализацию шаблонов и поддерживающем специализацию вообще только для глобальных классов и функций, остается открытым. Я такой возможности не вижу. Таким образом, создать без помощи препроцессора код нашего адаптера, компилирующийся и под gcc и под Visual C++, не представляется возможным.
Введем вспомогательный класс
template<class R>
struct gen_mem_fun_traits {
template<class T>
struct signature {
typedef gen_mem_fun_base_t<R, T> base;
};
};
template<> struct gen_mem_fun_traits<void> {
template<class T> struct signature {
typedef void_gen_mem_fun_base_t<T> base;
};
};
Этот класс специализирован для специального случая функции, возвращающей void. Таким образом, хоть нам и придется ввести дополнительный класс для функций, возвращающих void, для клиента это будет выглядеть единообразно: gen_mem_fun_traits<rettype>::signature<memberclass>::base.
Сами по себе ветви вычислений различных вариантов тривиальны:
template<class R, class T>
struct gen_mem_fun_base_t {
protected:
gen_mem_fun_base_t(R (T::*pm_)()): pm(pm_) {}
public:
template<class TT> R operator()(TT p) {return (p.operator->()->*pm)();}
template<> R operator()(T* p) {return (p->*pm)();}
private:
R (T::*pm)();
};
template<class T>
struct void_gen_mem_fun_base_t {
protected:
void_gen_mem_fun_base_t(void (T::*pm_)()): pm(pm_) {}
public:
template<class TT> void operator()(TT p) {(p.operator->()->*pm)();}
template<> void operator()(T* p) {(p->*pm)();}
private:
void (T::*pm)();
};
Теперь определим сам gen_mem_fun_t:
template<class R, class T>
struct gen_mem_fun_t: gen_mem_fun_traits<R>::template signature<T>::base {
typedef gen_mem_fun_traits<R>::template signature<T>::base base_;
explicit gen_mem_fun_t(R (T::*pm_)()): base_(pm_) {}
};
Один момент здесь требует пояснения: typedef используется для того, чтобы компилятор понял, какому предку нужно передать в конструктор наш указатель на функцию-член.
И, наконец, 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);
}
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
23.3. Частичная доставка
23.3. Частичная доставка Механизм частичной доставки (partial delivery) используется стеком SCTP каждый раз, когда требуется доставить приложению большое сообщение. Сообщение считается «большим», если SCTP решает, что у него недостаточно ресурсов на его обработку. Частичная доставка
Частичная специализация по виду аргумента шаблона
Частичная специализация по виду аргумента шаблона Одним из аспектов частичной специализации является возможность специализировать шаблон по виду аргумента, например, предоставить общую для всех указателей специализацию шаблона:template‹class T› class С { //…}; template‹class T› class
Специализация шаблонных функций – членов шаблонного класса
Специализация шаблонных функций – членов шаблонного класса К сожалению, вышеприведенный код не будет компилироваться на компиляторах, не поддерживающих специализацию шаблонов-функций – членов шаблонов классов.ПРИМЕЧАНИЕ К таким относятся, например, gcc-2.95 и gcc-2.96
11.2.2. Специализация отдельного объекта
11.2.2. Специализация отдельного объекта Я солипсист и, признаться, удивлен, что большинство из нас таковыми не являются. Из письма, полученного Бертраном Расселом В большинстве объектно-ориентированных языков все объекты одного класса ведут себя одинаково. Класс — это
Частичная сумма (Partial sum)
Частичная сумма (Partial sum) template ‹class InputIterator, class OutputIterator›OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result);template ‹class InputIterator, class OutputIterator, class BinaryOperation›OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);partial_sum присваивает каждому итератору i в диапазоне [result,
10.6. Явная специализация шаблона А
10.6. Явная специализация шаблона А Не всегда удается написать шаблон функции, который годился бы для всех возможных типов, с которыми он может быть конкретизирован. В некоторых случаях имеется специальная информация о типе, позволяющая написать более эффективную