2011-12-27 3 views
3

Ну, я в настоящее время реорганизую класс, который я сделал довольно давно. Класс - тип контейнера.избегая дублирования кода в константных и не константных функциях-членах

Многие функции могут использовать преимущества структуры классов и, таким образом, реализованы как функции-члены. Однако теперь, похоже, много функций, которые кажутся «то же самое», то есть «найти» функции:

iterator find(ITEM) 
const_iterator find(ITEM) const; 
iterator find_if(ITEM, PRED) 
const_iterator find_if(ITEM, PRED) const; 

4 «функции», чтобы описать почти то же самое (и код почти одинакова в каждой версии). Это становится очень утомительным при обновлении класса, я должен убедиться, что каждая версия обновлена. Есть ли способ справиться с этими вещами лучше? Некоторая другая функция в классе CAN может взять 2 предиката, а это значит, что у меня неожиданно было 8 функций для управления.

Я пробовал называть «непостоянную версию из постоянной версии», но это явно не работает.

Так как же можно справиться с этими вещами? Просто кусайте пулю и записывайте ее?

EDIT: только для того, чтобы сообщить: моя структура данных напоминает «дерево». Каждый «объект» содержит данные (которые ищут поиск) и «список» с поддеревами. Функция find работает рекурсивно по всем поддеревам дерева (и под-под деревьям). - Как и следовало ожидать при поиске дерева.

Поскольку для такого дерева не существует ясного итератора «end» или «start», использование std :: find не дает правильной функциональности.

+2

@FredOverflow: Отличная точка. Итераторы и алгоритмы существуют именно для решения проблемы, которую OP хочет снова опрокинуть. –

+1

@FredOverflow, Kerrek: Не совсем. Да, 'std :: find' существует, но так же' std :: map :: find', 'std :: set :: find' и т. Д. –

+1

@OliCharlesworth: Но нет' map :: find_if' :-) Да, когда это необходимо, предоставляете функцию-член, но не если она выполняет только то же, что и общий алгоритм. –

ответ

8

Скотт Мейерс решил аналогичную проблему в пункте 3 Эффективной C++ по константным версиям внутри неконстантной версии, а затем отливки константного результата обратно неконстантный:

const_iterator find(const T& value) const 
{ 
    // actual implementation of find 
} 

iterator find(const T& value) 
{ 
    return const_cast<iterator>(static_cast<const container*>(this)->find(value)); 
} 
Смежные вопросы