Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> указатель на функцию, возвращающий указатель функцию 
V
    Опции темы
fear
Дата 18.9.2007, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

Репутация: 1
Всего: 1



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

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

typedef int (*FUNC)();

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

typedef *FUNC (*FUNC)();

PM MAIL   Вверх
UnrealMan
Дата 18.9.2007, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Невозможно.
PM MAIL   Вверх
archimed7592
Дата 18.9.2007, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



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


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
fear
Дата 19.9.2007, 08:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

Репутация: 1
Всего: 1



Всё таки возможно  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();
}


Это сообщение отредактировал(а) fear - 20.9.2007, 15:03
PM MAIL   Вверх
Daevaorn
Дата 19.9.2007, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



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

через одно место и GC в С++ можно получить.
PM MAIL WWW   Вверх
Dov
Дата 19.9.2007, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



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

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

   



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
fear
Дата 20.9.2007, 06:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

Репутация: 1
Всего: 1



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

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


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

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

Это сообщение отредактировал(а) fear - 20.9.2007, 07:02
PM MAIL   Вверх
archimed7592
Дата 20.9.2007, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



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

Везде smile.


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

Garbage Collection.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Dov
Дата 20.9.2007, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Цитата(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 




--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
bsa
Дата 20.9.2007, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



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


Это сообщение отредактировал(а) bsa - 20.9.2007, 10:36
PM   Вверх
Dov
Дата 20.9.2007, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



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

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

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

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

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


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
bsa
Дата 20.9.2007, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Dov, согласен, я был не прав.
 
PM   Вверх
fear
Дата 20.9.2007, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

Репутация: 1
Всего: 1



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, Подробней можешь ответить?
PM MAIL   Вверх
bsa
Дата 20.9.2007, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



fear, лучше не заморачивайся и сделай возврат const void*, а при вызове делай преобразование типов. Как вариант, можно сделать через классы:
Код
class myClass
{
public:
          virtual myClass& operator()() {
                       ....
          }
};
Естественно, все возвращаемые классы должны быть потомками указанного.
PM   Вверх
Lazin
Дата 20.9.2007, 11:30 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Можно написать функтор возвращающий аналогичный функтор.

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

Код

#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;
}

PM MAIL Skype GTalk   Вверх
Dov
Дата 20.9.2007, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Цитата(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 Найти цитируемый пост)
указатель на аналогичную функцию





--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
fear
Дата 20.9.2007, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

Репутация: 1
Всего: 1



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();
}


Это сообщение отредактировал(а) fear - 20.9.2007, 15:03
PM MAIL   Вверх
UnrealMan
Дата 20.9.2007, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(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;
}

PM MAIL   Вверх
fear
Дата 20.9.2007, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

Репутация: 1
Всего: 1



Цитата(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;
}


Это сообщение отредактировал(а) fear - 20.9.2007, 15:27
PM MAIL   Вверх
UnrealMan
Дата 20.9.2007, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



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

А, ну да, я тогда мельком посмотрел на этот код, и подумал, что вся фича в преобразовании типа. Сейчас же что-то вообще не понимаю, в чём там, собственно, прикол.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0809 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.