Re: kylix 2
On Fri, Jan 10, 2003 at 06:40:33PM +0200, Dmitry Astapov wrote:
>
> Evening, Vlad.
>
> Vlad Harchev <hvv@hippo.ru> 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
Reply to: