On Fri, Jan 10, 2003 at 06:40:33PM +0200, Dmitry Astapov wrote: > > Evening, Vlad. > > Vlad Harchev <[EMAIL PROTECTED]> 18:21 10/1/2003 wrote: > > >> Нет. Совсем не аналогичный. Мы же не говорим о решении конкретной задачи, а > >> о демонстрации определенных принципов. > >> AS> #include <stdio.h> > >> > >> AS> #define POINT_V 64 > >> AS> #define VALUE_V 129 > >> > >> AS> int function(int x, int (*what_to_do)(int pnt), int point, int value); > >> AS> int function2(int x); > >> > >> Вопросы: > >> 1)Что надо сделать, чтобы решение работало для произвольных функций a -> b, > >> а не только для функций int -> int? При этом, решение должно быть type > >> safe. > > VH> На С++ - можно - используя шаблоны. > > Можно попросить продемонстрировать? > > >> AS> int main(int argc, char argv[]){ > >> AS> printf("function2 does: VALUE_V + 365; VALUE is: 129\n"); > >> AS> printf("Function returned on x == POINT_V: %i\n", > >> AS> function(POINT_V, &function2, POINT_V, VALUE_V)); > >> AS> printf("Function returned on x != POINT_V: %i\n", > >> AS> function(POINT_V+34, &function2, POINT_V, VALUE_V)); > >> > >> 2)В моем примере, overloadFunctionAtSpecificPoint возвращает объект типа > >> "функция", который затем можно использовать везде, где можно использовать > >> обычную функцию. Как сделать такое в С? Чтобы было что-то вроде: > >> new_function = function(&function2, POINT_V, VALUE_V)); > >> printf("It works: %d!\n", new_function(5)); > > VH> Да, это можно используя свойство языка С++ - шаблоны. > > Можно попросить продемонстрировать?
Когда будут правильно написаны шаблоны, то использование будет иметь вид: //с int printf("It works: %d!\n", (make_overriden_function(function2,POINT_V, VALUE_V)) (5)); //с string printf("It works: %s!\n", (make_overriden_function(str_function2, string("blah"), string("bar"))) ("bar").c_str() ); Принцип реализации make_overriden_function и прочего: //вспомогат. класс template<class F,class A,class R> class overriden_function { private: F& f; A& a; R& r; /*тут всякая инициализация, операторы копирования и прочая*/ /*..*/ /*а вот за счет этого все работает - */ R operator()(const A& av) const { return av == a ? r : f(av); } } //вспомогательная шаблонная ф-ия чтобы не приходилось всегда вручную задавать //параметры шаблонов template<class F,class A,class R> overriden_function<F,A,R> make_overriden_function(F &f,const A& a, const R& r) { return overriden_function<F,A,R>(f,a,r); } Еще пример использования ф-ии как об[екта: typedef int(*fn_t)(int); overriden_function<fn_t,int,int> fn = make_overriden_function(function2, POINT_V, VALUE_V); //далее используем fn как обычную ф-ию, хотя на самом деле это об[ект: printf("%d\n",fn(5)); //еще навороты overriden_function<overriden_function<fn_t,int,int>,int,int> fn2 = make_overriden_function(fn,-POINT_V,-VALUE_V); printf("%d\n",fn2(-5)); Я не хочу сказать что С++ лучше чем какие-либо языки, я просто хочу сказать, что в С++ это тоже возможно, но часто в более громоздкой форме. К сожалению, не все об этих возможностях С++ знают. > VH> А я вот хотел спросить - как делают структуры в лиспе (разных > диалектах)? > VH> Или обходятся списками, и считают элементы с определенным индексом - > членами? > Или списками, или соответствующими средствами для описания структур. > > VH> А в Haskel/Erlang/Clean - также, или все-таки есть аналог структур С? > > Там есть надмножество такого понятия, как структуры в С - называется > алгебраические типы (аналог из математики - прямая сумма декартовых > произведений). Пример: > > data Filter = Filter { active::Bool > , conduit::String > , fOrder::Integer > , fName::String > } deriving Show > > data Condition = Equals String String > | NotEqual String String > | StartsWith String String > | Larger String String Можно вопрос - а какая семантика у Condition? - отношение? А что, поддержка отношений имеется на уровне языков? > Примеры значений этих типов: (Filter True "one" 1 "someName"), (Equals "A" > "B"), (Larger "123" "0123"). > > Еще примеры: > > data Value = AsnOctString [Octet] > | I Int > | S { flags::[Octet], strBody::String } -- String with flags > | D { parsedDate::String, rawDate::OctetStream } -- Date > | T { parsedTime::String, rawTime::OctetStream } -- Time > deriving (Eq,Ord) > > data SR8Field = Prim Tag Value | Constr Tag [SR8Field] deriving (Eq,Ord) > > Примеры значений: Prim (Tag ...) (I 123), > Prim (Tag ...) (AsnOctString [1,2,123]), > Constr (Tag ...) [ Prim (Tag ...) (S [9,8] "abc"), Prim (Tag ...) (T > "12:24:23", [123,234,456]) ] Понятно. Спасибо за пояснения. -- Best regards, -Vlad