singlepost

[C/C++] Задачка рожденная больным мозгом. << На главную или назад  

Пока лежал в кровати и не мог уснуть в голову пришла мысль написать одну функцию.
Попытался решить в уме – не получилось.
Сон как рукой сняло.
( А завтра еще сидеть на работе и писать статью на FRUCT. А кто нить из вконактовцев пойдет? )

Задача:
1) Функция должна в качестве аргумента брать другую функцию, например DoIt().

[code]
int DoIt(float a, char b, char c)
{
printf("DoIt\n");
return a + b + c;
}
[/code]

Например так.
[code]
// <pt2Func> is a pointer to a function
void ptrAsArg(int (*pt2Func)(float, char, char))
{
(*pt2Func)(12, 'a', 'b');// call using function pointer
cout << result << endl;
}
[/code]

2) НО. Неизвестно количество входных аргументов в вызываемой функции DoIt().

Может быть так.
[code]
int DoIt(float a, char b, char c)
{
printf("DoIt\n");
return a + b + c;
}
[/code]

А может и так.

[code]
void DoIt()
{
printf("DoIt\n");
}
[/code]

Да и что возвращает функция – тоже не известно.

3) А еще не известно какого типа параметры в вызываемой функции =)

В общем, нихрена не известно, а сделать надо.

31 ответов в теме “[C/C++] Задачка рожденная больным мозгом.”

  1. 31
    Павел Потапов ответил:

    Ну… сравнения с жабскриптом бустовский function, конечно, не выдерживает, но для плюсов он очень неплох, особенно в связке с бустовским биндом.

    ЗЫ Леонид, спасибо за сцылко :)

  2. 30
    Vlad Ламбар ответил:

    Теперь понятно что это за объекты…такие функции и есть анонимными и замыкающими…в С++ такого нету…разве что эмуляция анонимных в boost :) ну или inline да макросы, но они должны быть определены где-то до этого, поэтому не подходят по определению :)

    #25 #27 #28 #29, может хватит флудить??

  3. 29
    Леонид Максимов ответил:

    по поводу объектов первого рода: //local.joelonsoftware.com/wiki/А_ваш_язык_прог...

  4. 28
    Глеб Раздолбаев ответил:

    Это квест вообще-то. Чуваки зависли на локации, которая называется "буст", им надо найти объект первого рода.

  5. 27
    Sasha Derkach ответил:

    с++это игра…чето типа рпг. ходишь по лабиринту и, проходишь туры, записуешь коды… та то пацаны гонят… *ролф*

  6. 26
    Глеб Белоус ответил:

    Всем привет! рсскажите мне кто-нибудь кто разбирается о C/C++. вообще что это и для чего это надо.

  7. 25
    Павел Потапов ответил:

    Я не в курсе, что за объекты первого рода? И почему ими можно (нельзя) считать boost::function?

  8. 24
    Глеб Раздолбаев ответил:

    #24:
    Некоторые пояснения можно найти здесь:
    //nlofoto.com/first_contact.html
    И здесь:
    //www.avada-kedavra.ru/transf/lek56.html

  9. 23
    Vlad Ламбар ответил:

    <offtop>
    #23 а что есть объекты первого рода? Да и наверно второго, третьего? А то я лично впервые слышу такое определение :)
    </offtop>

  10. 22
    Леонид Максимов ответил:

    неужели вы хотите сказать, что boost::function настолько удобен, что позволяет считать функцию объектом первого рода?

  11. 21
    Павел Потапов ответил:

    И параметры подбирает автоматом :)

  12. 20
    Павел Потапов ответил:

    И вообще, использование похоже на паттерн команда. Если я все правильно понимаю. А если неправильно, то рекомендую посмотреть на бустовский boost::function, если еще не смотрел :)

  13. 19
    Vlad Ламбар ответил:

    >>польза очевидна – вызов чего угодно, причем это что угодно материализуется в рантайме.
    хм…ну не знаю, не знаю…

    а как быть с анонимными функциями, замыканием, каррированием в лямбда-исчислениях…
    Разве не это результат? Как по мне похоже именно оно…или же вопрос добится сего в С++?
    Если да то эмуляция анонимных функций есть в boost…насчет замыкания сложно сказать, не знаю такого для С++

  14. 18
    Леонид Максимов ответил:

    польза очевидна – вызов чего угодно, причем это что угодно материализуется в рантайме.

  15. 17
    Vlad Ламбар ответил:

    А собственно зачем вот это, вот? Какая цель? Какая польза?

  16. 16
    Евгений Гаврин ответил:

    Интересно. Надо будет попробовать

  17. 15
    Андрей Горбоконь ответил:

    > Соответственно __asm call DoIt и тут тоже не получиться.

    __asm
    {
    push par_1
    push par_2

    push par_n
    call DoIt
    pop par_n

    pop par_2
    pop par_1
    mov result, eax
    }

    как вы видите этому коду абсолютно пофиг сколько у вас параметров и какого они типа, а также тип возвращаемого значения.

    правда если ошибится, то получите не ошибку компиляции, а ошибку рантайма.

  18. 14
    Евгений Гаврин ответил:

    Леонид, многоточие тут не подойдет по той причине, что нам не известно ни количество, ни типы аргументов вызываемой функции. Мы просто не сможем аргументы получить, а раз так, то и вызвать ее не получиться.

    Соответственно __asm call DoIt и тут тоже не получиться.
    Или я в последнем утверждении ошибаюсь?

  19. 13
    Андрей Горбоконь ответил:

    Леонид maxleo Максимов,
    многоточие не справится со следующим условием:

    > Да и что возвращает функция – тоже не известно.

  20. 12
    Леонид Максимов ответил:

    в примерах в первом посте скорее выражено "что возвращает функция – не важно".

  21. 11
    Леонид Максимов ответил:

    я, конечно, им особо не пользовался, но оно есть – многоточие из C здесь не пройдет?

  22. 10
    Vitaly Martynovich ответил:

    Неужели это так важно?)
    <offtop>
    С вами не поспоришь
    </offtop>

  23. 9
    Андрей Горбоконь ответил:

    Поддерживаю, imho, решение при помощи ассемблера наиболее красивое, кстати вызывать можно без указателя:
    __asm call DoIt

    <offtopic>
    А судя по анкете – он студент
    </offtopic>

  24. 8
    Глеб Раздолбаев ответил:

    Забавно: только участник под #7 правильный вопрос задал. Судя по фотке, спец старой заказки:) И решение, кстати, правильное подсказал:)

  25. 7
    Евгений Гаврин ответил:

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

    [code]
    (*pt2Func)(12, 'a', 'b'); // call using function pointer
    [/code]

    Передаваемой может быть любая функция.
    Внутри ее необходимо вызвать.

  26. 6
    Vitaly Martynovich ответил:

    А как ты хочешь вызвать функцию, если не знаешь даже список параметров которые нужно передать? Или неважно что передавать?

    Если не важно, то можно объявить DoIt как __cdecl, а вызывать примерно так
    void* f = (void) pt2Func;
    __asm call f

  27. 5
    Виктор Шаевский ответил:

    а не проще было DOIT сделать как функцию с неограниченым количеством параметров + а во вторую функцию передать допустим айдишник той функции или указатель на функцию?

  28. 4
    Евгений Гаврин ответил:

    Я придумал грабли.
    Для моих целей сгодились, но решение не универсальное, а заточенное под свою задачу.

    Если интересно могу скинуть результат.

    Работает так:
    [code]
    blaBlaMagic
    {
    // Кусок кода
    }
    [/code]
    или просто
    [code]
    blaBlaMagic
    DoIt ();
    [/code]

  29. 3
    Андрей Горбоконь ответил:

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

    >получить в свое распоряжение следующий за вызовом
    воспользоваться метками?

  30. 2
    Евгений Гаврин ответил:

    Не очень подходит. Вызываемые функции могут быть разные и в огромном количестве.

    Я тут подумал вот о чем.
    Реально ли получить в свое распоряжение следующий за вызовом функции/макроса/хзчего блок кода.

    Например:

    [code]
    blaBlaMagic
    {
    // Кусок кода
    }
    [/code]
    или просто
    [code]
    blaBlaMagic
    DoIt ();
    [/code]

  31. 1
    Андрей Горбоконь ответил:

    Как вариант: сделать класс-обертку и в зависимости от количества параметров или их типа – вызывать нужный вариант функции

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.