Программирование >>  Обобщенные обратные вызовы 

1 ... 64 65 66 [ 67 ] 68 69 70 ... 84


Решение 1 является несколько подчищенной версией кода, сохраняющей общую структуру исходного варианта, код сократился с 23 до 17 строк (даже если считать public: и private: отдельными строками), namespace Solutionl {

tempiate<class lter>

class sort idxtbl pai г {

public:

void setCconst lter& it, int i) {it = it; i = i;} bool operator<(const sort idxtbl pair& other) const

{ return *it < *other.it ; } operator int() const { return i ; } private:

Iter it ; int i ;

Эта функция претерпела самые существенные изменения, сократившись с 13 строк до 5. Для сравнения я сохранил весь старый код. Старайтесь писать программы так, чтобы в них не было излишней сложности

tempiate<class iterin, class iterout>

void sort idxtbl(iterin fi rst, iterin last, iterout out){

std::vector<sort idxtbl pair<iterin> > v(last-first); i nt iDst = 1ast-fi rst;

typedef std::vector< sort idxtbl pair<RAlter> > V; V v(iDst);

for( i nt i=0; i < 1ast-fi rst; ++i )

v[i].set( first+i, i ); . int i=0; RAlter it = first; v;:iterator vit = v.begin(); for (i=0; it<last; it++, vit++, i++) (*vit).set(it,i); std: :sort( v.beqin() , v.endO ) ; std::sort(v.begi n(), v.end()); std: : copy( v. begi n() , v.endO, out ) ; int *pi = pidxtbl; vit = V.beginO ; for (; vit<v.end(); pi++, vit++) *pi = (*vit) .i;

Решение 2 использует класс pair вместо вспомогательного класса, код уменьшился до 15 строк (из них 2 - продолжение предыдущих из-за ширины страницы). 8 строк специфичны для данного кода, а 4 строки в принципе можно непосредственно использовать и в других контекстах.

namespace Solution2 {

tempiate<class т, class u> struct ComparePairlstDeref {

bool operatorO(const std::pair<T,U>& a,

const std::pair<T,u>& b ) const { return *a.first < *b.first; }

tempiate<class Iterin, class Iter0ut>

void sort idxtbl(Iterin fi rst, Iterin last, Iterout out){ std::vector< std::pair<iterin,int> > s( last-first ); for( int i=0; i < s.sizeO; ++i )

s[i] = std::make pair( first+i, i );



std: :sort(s.begin(), s.endO,

ComparePai rlstDeref<lterln,int>()); for( int i=0; i < s.sizeC); ++i, ++out ) *out = s[i].second;

Решение 3 демонстрирует пару альтернативных деталей - в нем используется тар для того, чтобы избежать отдельного этапа сортировки, и std::transformC) вместо вручную написанного цикла, код сократился до 16 строк и стал существенно более повторно используемым, этой версии требуется больше памяти и, вероятно, ее производительность немного ниже, так что мне больше нравится решение 2. Этот код - пример поиска альтернативного решения задачи.

namespace solutions { tempiate<class т> struct CompareDeref {

bool operatorOC const т& a, const т& b ) const { return *a < *b; }

tempiate<class т, class u> struct Pair2nd {

const u& operatorOC const std: :pai r<T,u>& a ) const { return a.second; }

tempiate<class iterin, class Iter0ut>

void sort idxtblCiterin fi rst, iterin last, Iterout out){ std::multimap<lterin, int, CompareDeref<IterIn> > v; forC int i=0; first != last; ++i, ++first ) v.insertC std::make pairC fi rst, i ) ); std::transform(v.begin(), v.endC), out,

pair2nd<Iterln const,int>C));

тестовая часть кода осталась по сути неизменной, за исключением использования итератора для получения результата (вместо int*) и использования исходного массива непосредственно в качестве контейнера.

#include <iostream> int main() {

int ai[10] = { 15,12,13,14,18,11,10,17,16,19 };

std::cout ################# std::endl;

std::vector<int> aidxtbl( 10 );

для тестирования другого решения используйте

соответствующее имя пространства имен

solutions::sort idxtbl( ai, ai+10, aidxtbl.begin() );

for( int i=0; i <10; ++i )

std::cout i= i

, aidxtbl[i]= aidxtbl[i]

, ai [aidxtbl [i]]= ai [aidxtbl [il]

std: :endl;

std::cout ################# std::endl;



Задача 35. Обобщенные обратные вызовы Сложность: 5

Отчасти привлекательность обобщенного кода состоит в возможности его использования во всех ситуациях, которые только можно представить. Каким образом можно стилистически улучшить представленное в цитируемой статье средство, и каким образом можно сделать его более полезным, чтобы это был действительно обобщенный широко

используемый код?

Вопрос для новичка

1. Какие качества целесообразны при разработке и написании обобщенных средств? Поясните свой ответ.

Вопрос для профессионала

2. Показанный далее код представляет интересную и очень полезную идиому для оболочек функций обратного вызова. Более детальное описание вы можете найти в оригинальной статье [KalevOl].

Отрецензируйте предложенный код и определите:

а) возможные стилистические улучшения дизайна для лучшего идиоматического использования С++;

б) механические ограничения полезности данного средства.

template < class т, void (t::*f)() > class callback

public:

Присваивание члену object callback(t& t) : obiect(t) {} Запуск функции обратного вызова void executeO {(object.*f)();} private:

t& object;

Решение

Качества обобщенности

I. Какие качества целесообразны при разработке и написании обобщенных средств? Поясните свой ответ.

Обобщенный код прежде всего должен быть практичен и удобен в использовании. Это не значит, что он должен включать все возможные варианты использования, включая варку кофе и мытье посуды. Это всего лишь означает, что в отношении обобщенного кода следует стараться избегать как минимум трех вещей.

/. Избегайте чрезмерного ограничения типов. Например, если вы пишете обобщенный контейнер, то вполне разумно потребовать, чтобы содержащиеся в нем элементы имели, скажем, копирующий конструктор и не генерирующий исключений деструктор. Но надо ли требовать конструктор по умолчанию или оператор присваивания? Многие полезные типы, которые пользователи могут захотеть хранить в вашем контейнере, не имеют конструкторов по умолчанию, и если наш контейнер их использует, то такой тип не может быть использован в качестве типа элементов контейнера. Согласитесь, это не слишком обобщенно... (В качестве примера можно привести задачу 11 и се контекст из [SutterOO] (задача 2.4 в русском издании).)



1 ... 64 65 66 [ 67 ] 68 69 70 ... 84

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика