[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: