Dmitry Astapov wrote:
Evening, Andrei.
Andrei Sosnin <[EMAIL PROTECTED]> 19:04 9/1/2003 wrote:
AS> Dmitry Astapov wrote:
DA>> DA>> И как на C правильно реализуется map и fold? А так, чтобы
было type-safe? А
DA>> рекурсивные функции? А с tail-recursive оптимизацией?
DD> что есть map, fold и tail-recursive оптимизация?
Функции такого вида (я, да простят меня, решил демонстрировать на
примерах...):
map :: (a -> b) -> [a] -> [b]
(дали функцию и список, получили список, к каждому эл-ту которого применена
эта ф-я)
AS> В С++ это делается так:
AS> foreach(list_iterator.first, list_iterator.last, function_obj);
AS> Где:
AS> list_iterator.first, list_iterator.last - итераторы,
AS> указывающие на начало и конец списка (контейнера);
AS> function_obj - объект-функция.
Только отгремели баталии в su.softw :)
Какой тип у foreach и function_obj? Подсказка: "void *" - это несерьезно.
?!! Как это?! 8-\
В С++ эти элементы имеют определенные типы! Они, правда, подводятся под
шаблоны, но проверка типов там строгая, и трюки с void * там не пройдут
- придется применять специальные операторы-функции: static_cast или
dynamic_cast! Вот точное, концептуальное определение данной функции (из
STL):
template<class In, class Op> Op for_each( In first, In last, Op f){
while (first != last) f(*first++);
return f;
}
И заметьте, что "*" в С++ - перегружаемый оператор, поэтому first
является объектом определенного типа (например, istream::iterator), но
не указателем, как в С. Хотя он абстрагирует понятие указателя... Но это
совсем другое.
Проверка типов является одним из приоритетов С++. Это, так сказать,
"строго типизированный язык".
Каким образом происходит проверка того, что function_obj принимает аргумент
именно того типа, который содержится в списке?
Можно ли сделать:
foreach(list_iterator.first, list_iterator.last,
foreach(other_list_iterator.first, other_list_iterator.last, function_obj));
(это синтаксически неверно, но идея должна быть понятна. Если для этого
нужно более 3 строк кода, то хорошо ли это?)
Почему нельзя? Можно! И синтаксически все правильно - мы говорим о С++ в
данном случае (см. выше: "> AS> В С++ это делается так:") (извините,
незаметно переменил подтему). Именно для этого и писалась эта
стандартная алгоритмическая функция, чтобы можно было
объектно-ориентированными средствами языка имитировать кострукции вида:
for(Iterator counter; counter != container.end(); counter++){
for(Iterator counter2; counter2 != container[1].end(); counter2++){
// do smth...
}
}
На С, конечно, для написания такой функции было бы не обойтись без (void
*). На С++ эта проблема была решена.
--
Andrei Sosnin
http://zzx.ath.cx
<!-- : it all depends on your vision : -->