Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > указатель на функцию


Автор: fear 18.9.2007, 14:26
Возможно ли объявить указатель на функцию, результатом выполнения которой являлся бы указатель на аналогичную функцию?

Например, указатель на функию, результатом выполнения которой является значение типа int:
Код

typedef int (*FUNC)();

Нужно что то типа:
Код

typedef *FUNC (*FUNC)();

Автор: UnrealMan 18.9.2007, 14:38
Невозможно.

Автор: archimed7592 18.9.2007, 14:52
fear, ну это точно также как объект содержащий самого себя. Никогда не смотрел в два стоящих друг напротив друга зеркала? Ситуация аналогичная.

Автор: fear 19.9.2007, 08:17
Всё таки возможно  smile 

Код

class FF;
typedef FF (*FUNC1)();
class FF
{
  public:
    FF():func(0) {};
    ~FF() {};

    FUNC1 func;
};
FF func_one();
FF func_two();

void main()
{
  FF result = func_one();
  if(result.func)
    result.func();
}

FF func_one()
{
  FF result;
  result.func = func_two;

  cout<<"func_one"<<endl;
  
  return result;
}

FF func_two()
{
  cout<<"func_two"<<endl;

  return FF();
}

Автор: Daevaorn 19.9.2007, 09:23
Цитата(fear @  19.9.2007,  09:17 Найти цитируемый пост)
Всё таки возможно 

через одно место и GC в С++ можно получить.

Автор: Dov 19.9.2007, 22:49
Цитата(fear @  18.9.2007,  13:26 Найти цитируемый пост)
Возможно ли объявить указатель на функцию, результатом выполнения которой являлся бы указатель на аналогичную функцию?Например, указатель на функию, результатом выполнения которой является значение типа int:

Если я правильно разобрался в этих словесных хитросплетениях(хотя не уверен в этом до конца), то тебе нужен указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int.
Если это так, то вот: 
Код
int (*(*p)())();

   

Автор: fear 20.9.2007, 06:57
Цитата(Dov @ 19.9.2007,  22:49)
Если я правильно разобрался в этих словесных хитросплетениях(хотя не уверен в этом до конца), то тебе нужен указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int.

не правильно  smile 
Вопрос был следующий:
Цитата(fear @ 18.9.2007, 14:26)
Возможно ли объявить указатель на функцию, результатом выполнения которой являлся бы указатель на аналогичную функцию?


Добавлено @ 07:00
Цитата(Daevaorn @ 19.9.2007,  09:23)
через одно место и GC в С++ можно получить.

А где в примере одно место? И что такое GC?

Автор: archimed7592 20.9.2007, 07:30
Цитата(fear @  20.9.2007,  06:57 Найти цитируемый пост)
А где в примере одно место?

Везде smile.


Цитата(fear @  20.9.2007,  06:57 Найти цитируемый пост)
И что такое GC?

Garbage Collection.

Автор: Dov 20.9.2007, 09:53
Цитата(fear @  20.9.2007,  05:57 Найти цитируемый пост)
не правильно

Ok.  smile 
Цитата(fear @  18.9.2007,  13:26 Найти цитируемый пост)
Например, указатель на функию, результатом выполнения которой является значение типа int:

Стало быть, у тебя есть ф-ция, возвращающая int и, плюс  к этому, указатель на неё. Я правильно понял?  smile 
Тогда начнём сначала.
Код

// ф-ция,возвращающая int
int fi()                      
{
    cout << "fi" << endl;
    return 1;
}

// ф-ция, возвращающая указатель на ф-цию, возвращающую int
int (*pfi())()                
{
    // указатель на ф-цию,возвращающую int
    int (*p)() = fi;          
    p();
    cout << "pfi" << endl;
    
    return p;
}

// ф-ция, возвращающая указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int
int (*(*pfpfi())())()
{
    // указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int 
    int (*(*p)())() = pfi;
    p();
    cout << "pfpfi" << endl;
    
    return p;
}
 
int main()
{    
    // указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую указатель на ф-цию,возвращающую int 
    int (*(*(*p)())())() = pfpfi;
    p();
    
    return 0;
}


Что из этого тебе нужно?  smile 


Автор: bsa 20.9.2007, 10:35
Имхо, в приведенном Dov коде есть ошибка. int (*xxx)() - это указатель по имени xxx на функцию возвращающую int, а не функция, возвращающая указатель. Лучше писать так:
Код
typedef int (*IntFunc)();
int myfunc1()
{
      ...
}
IntFunc myfunc()
{
      ...
      return &myfunc1;
}
...
В этом случае накосячить шансов меньше. Но если очень хочется без typedef (например, чтобы запутать врага):
Код
int myfunc1()
{
      ...
}
int(*)() myfunc()
{
      ...
      return &myfunc1;
}
...

Автор: Dov 20.9.2007, 10:41
Цитата(bsa @  20.9.2007,  09:35 Найти цитируемый пост)
Имхо, в приведенном Dov коде есть ошибка. int (*xxx)() - это указатель по имени xxx на функцию возвращающую int, а не функция, возвращающая указатель.

Никакой ошибки в моём коде нет.

Добавлено через 4 минуты и 13 секунд
Цитата(bsa @  20.9.2007,  09:35 Найти цитируемый пост)
а не функция, возвращающая указатель

а где у меня написано, что это функция?   smile 

bsa, смотри внимательнее.  smile 

Автор: bsa 20.9.2007, 10:51
Dov, согласен, я был не прав.
 

Автор: fear 20.9.2007, 10:58
Dov, ты взрываешь мой мозг. smile

Меня интерисовало, можно ли объявить указатель на функцию, результатом выполнения которой являлся бы указатель на аналогичную функцию? Т.е. функция возвращающая себе аналогичную фунцию.
Для большего понимания вопроса был приведён пример объявления указателя на функцию, возвращающую int.
Цитата(fear)

Например, указатель на функию, результатом выполнения которой является значение типа int:
Код

typedef int (*FUNC)();


и пример желаемого результата
Цитата(fear)

Нужно что то типа:
Код

typedef *FUNC (*FUNC)();


Надеюсь, я смог объяснить что требовалось. Решение содержит 4й пост. Если имеются мысли альтернативного решения, будет интересно взлянуть.

Добавлено через 5 минут и 23 секунды
Цитата(archimed7592 @ 20.9.2007,  07:30)
Цитата(fear @  20.9.2007,  06:57 Найти цитируемый пост)
А где в примере одно место?

Везде smile.

archimed7592, Подробней можешь ответить?

Автор: bsa 20.9.2007, 11:13
fear, лучше не заморачивайся и сделай возврат const void*, а при вызове делай преобразование типов. Как вариант, можно сделать через классы:
Код
class myClass
{
public:
          virtual myClass& operator()() {
                       ....
          }
};
Естественно, все возвращаемые классы должны быть потомками указанного.

Автор: Lazin 20.9.2007, 11:30
Можно написать функтор возвращающий аналогичный функтор.

Этот идиотский пример тому подтверждение:

Код

#include "stdafx.h"
#include <iostream>
class foo
{
    int num;
public:
    foo(int i):num(i)
    {
    }

    foo operator()()
    {
        static int calls = 0;
        std::cout << "object: " << num << " calls: " << calls << std::endl;
        return foo(++calls);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    foo f(0);
    f()()()()()();
    char ccc;
    std::cin >> ccc;
    return 0;
}

Автор: Dov 20.9.2007, 12:18
Цитата(fear @  20.9.2007,  09:58 Найти цитируемый пост)
Dov, ты взрываешь мой мозг

В каком смысле? 

Цитата(fear @  20.9.2007,  09:58 Найти цитируемый пост)
Меня интерисовало, можно ли объявить указатель на функцию, результатом выполнения которой являлся бы указатель на аналогичную функцию?

Так я ж, вроде, это и написал.  smile 

Ну, давай переделаем так, как ты хочешь, с typedef`ами.  smile 
Код

typedef int   (*pFi)();
typedef pFi   (*pFpFi)();

// ф-ция,возвращающая int
int fi()                      
{
    cout << "fi" << endl;
    return 1;
}

// ф-ция, возвращающая указатель на ф-цию, возвращающую int
pFi pfi()                
{
    // указатель на ф-цию,возвращающую int
    pFi p = fi;          
    p();
    cout << "pfi" << endl;
    
    return p;
}

// ф-ция, возвращающая указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int
pFpFi pfpfi()
{
    // указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int 
    pFpFi p = pfi;
    p();
    cout << "pfpfi" << endl;
    
    return p;
}
 
int main()
{    
    // указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int 
    pFpFi p = (pFpFi)pfpfi;
    p();
    
    return 0;
}



fear, видишь указатель в main? Что это по-твоему, если  не 
Цитата(fear @  20.9.2007,  09:58 Найти цитируемый пост)
указатель на аналогичную функцию



Автор: fear 20.9.2007, 14:17
Dov, попытаюсь объяснить по другому. Мне не нужен:
Цитата(Dov @  20.9.2007, 12:18)
указатель на ф-цию, возвращающую указатель на ф-цию, возвращающую int

Мне нужен указатель на ф-цию, возвращающую указатель на аналогичную ф-цию.

int - ненужен вообще, идея в том, что функция - это набор операций, в случае необходимости функция должна вернуть другую ф-цию (другой набор операций) или 0 - если других операций производить не надо

Пример в догонку, класс A реализует выполнение цикла операций/действий содержащихся в произвольных функциях
Код
class FF;
typedef FF (*FUNC1)();
class FF
{
  public:
    FF():func(0) {};
    ~FF() {};

    FUNC1 func;
};
FF func_one();
FF func_two();

class A
{
  public:
    A() {};
    ~A() {};

    void exec() const;
    void setFunc(const FUNC1 func);

  private:
    FUNC1 func_;
};

void A::exec() const
{
  FF result = func_();
  while(result.func)
    result = result.func();
}

void A::setFunc(const FUNC1 func)
{
  func_ = func;
}

void main()
{
  A a;

  //// Пример 1: необходимо совершить операции ф-ции func_one
  a.setFunc(func_one);
  a.exec();

  //// Пример 2: необходимо совершить операции ф-ции func_two
  a.setFunc(func_two);
  a.exec();
}

//// Функция производит ряд операций/действий и возвращает указатель на функцию, содержащую следующие действия
FF func_one()
{
  FF result;
  result.func = func_two;

  std::cout<<"func_one"<<std::endl;
  
  return result;
}

//// Функция производит ряд операций/действий и возвращает признак завершения всех операиций
FF func_two()
{
  std::cout<<"func_two"<<std::endl;

  return FF();
}

Автор: UnrealMan 20.9.2007, 14:21
Цитата(fear @  19.9.2007,  09:17 Найти цитируемый пост)
Всё таки возможно

И где тут объявление указателя с обозначенными требованиями? Ты всего лишь сделал reinterpret_cast.

Поведение таких указателей можно разве что сымитировать

Код

#include <iostream>

struct FuncPtr
{
    typedef FuncPtr (*FPtr)();
    FuncPtr(FPtr fptr = 0) : fptr(fptr) {}
    operator FPtr() const { return fptr; }
    FuncPtr operator ()() const { return fptr(); }
private:
    FPtr fptr;
};

FuncPtr f() { return &f; }

int main()
{
    FuncPtr fptr1 = f();
    FuncPtr fptr2 = fptr1();
    std::cout << (fptr1==fptr2) << std::endl;

    return 0;
}

Автор: fear 20.9.2007, 15:07
Цитата(UnrealMan @ 20.9.2007,  14:21)
И где тут объявление указателя с обозначенными требованиями? Ты всего лишь сделал reinterpret_cast.

Выше на один пост твоего, reinterpret_cast не знаю даже зачем использовал, исправил код, работает и без него

UnrealMan, отличный пример, это мне и хотелось увидеть в самом начале, переделал его под свои нужды:
Код
#include <iostream>

struct FuncPtr
{
    typedef FuncPtr (*FPtr)();
    FuncPtr(FPtr fptr = 0) : fptr(fptr) {}
    operator FPtr() const { return fptr; }
    FuncPtr operator ()() const { return fptr(); }
  private:
    FPtr fptr;
};

class A
{
  public:
    A() {};
    ~A() {};

    void exec() const;
    void setFunc(const FuncPtr &func);

  private:
    FuncPtr func_;
};

void A::exec() const
{
  FuncPtr fptr = func_();

  while(fptr)
    fptr = fptr();
}

void A::setFunc(const FuncPtr &func)
{
  func_ = func;
}

FuncPtr func_one();
FuncPtr func_two();

int main()
{
  A a;
  a.setFunc(func_one);
  a.exec();

  return 0;
}

FuncPtr func_one()
{
  std::cout<<"func_one"<<std::endl;
  return &func_two;
}

FuncPtr func_two()
{
  std::cout<<"func_two"<<std::endl;
  return 0;
}

Автор: UnrealMan 20.9.2007, 16:22
Цитата(fear @  20.9.2007,  16:07 Найти цитируемый пост)
Выше на один пост твоего, reinterpret_cast не знаю даже зачем использовал, исправил код, работает и без него

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)