Форум программистов, компьютерный форум CyberForum.ru

Функция должна принять указатель на саму себя - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 8, средняя оценка - 4.75
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
07.01.2014, 22:48     Функция должна принять указатель на саму себя #1
не рекурсия. (ошибка в названии)
Функция должна принять указатель на саму себя.
моя неверная попытка имеет вид
C++
1
2
3
4
5
6
7
8
9
10
11
int myfunc(int (*P)(int))  принимаю указатель на функцию
{
   return 0;
}
 
int main()
{
  int (*P)( int (*)(int) ); //создаю указатель на функцию
  P=myfunc; //присваиваю в указатель адрес функции
  myfunc(P); //попытка передарь функции указатель на саму себя. неверная.
}
Это как делается?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.01.2014, 22:48     Функция должна принять указатель на саму себя
Посмотрите здесь:

Функция вызывает сама себя 10 раз C++
Функция должна возвращать указатель на первый элемент массива,удовлетворяющий условию C++
C++ Функция должна вернуть 4 параметра
C++ Деструктор для класс, имеющий указатель на самого себя
C++ Подскажите немножко с рекурсией ( Функция должна вызывать сама себя до тех пор пока sum не станет больше х)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
08.01.2014, 20:03     Функция должна принять указатель на саму себя #21
Чуть подумав, понимаешь, что этого не может быть потому, что этого не может быть никогда. Разве что обмануть компилятор. Но смысл?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
hoggy
5030 / 2113 / 403
Регистрация: 15.11.2014
Сообщений: 4,797
Завершенные тесты: 1
21.09.2015, 17:20     Функция должна принять указатель на саму себя #22
http://rextester.com/SBI46430

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <functional>
 
void foo(const struct myself& f, const size_t depth);
 
struct myself
{
    template<class T> myself(T&& v)
        :mCaller( std::bind(foo, foo, std::placeholders::_1) )
    {}
    
    void operator()(const size_t depth)const 
        { mCaller(depth); }
    
    std::function<void(const size_t)> 
        mCaller;
};
 
void foo(const myself& f, const size_t depth)
{
    if(depth == 0)
        return;
    
    std::cout<<"depth recursieve: "<< depth << '\n';
    f(depth - 1);
}
 
int main()
{
    std::cout << "Hello, world!\n";
    
    foo(foo, 10);
}
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 17:34  [ТС]     Функция должна принять указатель на саму себя #23
Как бы я в этом коде ничего не понял. Небольшие разъяснения наиболее важных участков могут оказаться полезны не только мне.
Цитата Сообщение от hoggy Посмотреть сообщение
foo(foo, 10);
Вовнутрь функции передается функция., а должен был указатель на неё. Т.е. созданный указатель, который указывает на foo должен был передаться вовнутрь foo., а не foo вовнутрь foo.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,829
Записей в блоге: 2
Завершенные тесты: 1
21.09.2015, 17:41     Функция должна принять указатель на саму себя #24
daslex, это не реализуемо

Добавлено через 1 минуту
В древности этим преподаватели якобы"убивали" зарвавшихся студентов
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 17:42  [ТС]     Функция должна принять указатель на саму себя #25
Croessmah, мне не верят. Я в курсе.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,829
Записей в блоге: 2
Завершенные тесты: 1
21.09.2015, 17:42     Функция должна принять указатель на саму себя #26
Цитата Сообщение от daslex Посмотреть сообщение
мне не верят.
ну пусть покажут как, посмотрим.
DrOffset
6416 / 3790 / 876
Регистрация: 30.01.2014
Сообщений: 6,575
21.09.2015, 18:23     Функция должна принять указатель на саму себя #27
daslex,
Без хаков с приведением типов и используя лишь функции С++ это не реализуемо. Концептуально.
По очень простой причине. Функции в С++ не объекты первого класса. В этом нет ничего удивительного, т.к. концепция функции унаследована из С, который не задумывался как объектно-ориентированный язык.
Зато С++ предоставляет альтернативный механизм - функторы.
Функторы - это функциональные объекты, и они являются объектами первого класса. Поэтому такой код в С++ будет работать и в какой-то степени решает поставленную задачу:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Func
{
    void operator()(Func & func, int i = 0)
    {
        if(i < 10) // чтобы разорвать рекурсию.
        {
            func(*this, i + 1);
        }
    }
};
 
 
int main()
{
    Func f;
    
    f(f);
}
daslex
21.09.2015, 18:27  [ТС]
  #28

Не по теме:

Да мне не надо это доказывать. Эта тема воскресла потому как я дал на нее ссылку из другой темы. Я имел наглость заявить, что С++ умеет не всё и мне, разумеется, никто не поверил. Эта тема под руку попалась как одна из небольшого множества нерешаемых задач, которые я видел и которую я смог вспомнить.

DrOffset
6416 / 3790 / 876
Регистрация: 30.01.2014
Сообщений: 6,575
21.09.2015, 18:40     Функция должна принять указатель на саму себя #29
Цитата Сообщение от daslex Посмотреть сообщение
мне не верят.
Не верят потому, что ты неправильно возражаешь.
Тут нужна железная аргументация, а не попытки холиварить
Многие, кто с тобой спорит, на самом деле знают, что этого сделать в чистом виде нельзя.
Но из-за слабой аргументации с твоей стороны, не могут себе позволить просто так сдаться.
Например, в соседней теме ты категорически не прав, приплетая boost, как доказательство того, что С++ чего-то не может. Вот этот пример, с функцией - доказательство. Слабое, т.к. есть эмулирующие механизмы, но это не важно, факт есть факт - нельзя.
А вот boost и вообще библиотеки на С++ - это не в кассу. Знаешь почему? Потому что любой плюсовик знает, что концепция языка закладывалась с тем расчетом, чтобы получить относительно маленькое ядро языка, но которое позволяет с помощью своих возможностей реализовать практически любую функциональность. Почитай Страуструпа. Они в комитете иногда намеренно не вносили изменения в стандарт. Потому что было известно, что это хорошо реализуется на уровне библиотеки. Да, черт возьми, библиотека iostreams отдельно от языка - это намеренное опровержение от Страуструпа утверждения, что якобы нельзя сделать эффективную библиотеку ввода-вывода вне ядра языка.
Поэтому приводя аргументом boost, ты вызываешь когнитивный диссонанс. Не может средству, которое задумывалось как "набор инструментов, чтобы построить почти любой дом" вменяться в вину, что оно выполняет свое прямое назначение. Это нонсенс.
Почитай "Дизайн и Эволюцию". Хочешь воевать на этом поле - изучай материал. Наехать на С++ можно. У него много изъянов, но надо знать язык, чтобы в них попадать.

Добавлено через 1 минуту
Цитата Сообщение от daslex Посмотреть сообщение
Да мне не надо это доказывать.
Господи, да выключи уже самолюбие и слушай.
Я не доказываю тебе ничего. Я тебе расставляю точки над i.
Чтобы ты знал куда давить в таких спорах. Об образовании твоем забочусь, между прочим
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 18:46  [ТС]     Функция должна принять указатель на саму себя #30
Пусть с boost я категорически не прав. От boost я перешел к WinApi. Смысл абсолютно тот же самый, когда я сослался на Boost. Всё из этой же оперы почему я на него сослался.
Но об этом всем надо в той теме писать. Тут по этой, там по той.

Возражаю как умею.
hoggy
5030 / 2113 / 403
Регистрация: 15.11.2014
Сообщений: 4,797
Завершенные тесты: 1
21.09.2015, 18:56     Функция должна принять указатель на саму себя #31
Цитата Сообщение от daslex Посмотреть сообщение
Вовнутрь функции передается функция., а должен был указатель на неё. Т.е. созданный указатель, который указывает на foo должен был передаться вовнутрь foo., а не foo вовнутрь foo.
ну на самом деле передача foo(foo);
это тоже самое, что и foo(&foo);

следущий пример иллюстрирует это положение:

http://rextester.com/BICQ84301

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <functional>
 
class recursivePointer
{
    typedef std::function<void(const size_t)> 
        functor;
public:
    template<class T> recursivePointer(T&& v)
        :mCaller( std::bind(v, v, std::placeholders::_1) )
    {}
    
    recursivePointer(const functor& v)
        :mCaller(v)
    {}
    recursivePointer(functor&& v)
        :mCaller( std::move(v) )
    {}
    
    void operator()(const size_t depth)const 
        { mCaller(depth); }
    
    operator const functor&()const
        { return mCaller; }
    
private:    
    functor mCaller;
};
 
void foo(const recursivePointer& f, const size_t depth)
{
    if(depth == 0)
        return;
    
    std::cout<<"depth recursieve: "<< depth << '\n';
    f(depth - 1);
}
 
int main()
{
    std::cout << "Hello, world!\n";
    
    const auto pFunc = recursivePointer(&foo);
    
    foo(pFunc, 10);
    std::cout<< "--------------\n";
    
    foo(foo, 10);
    std::cout<< "--------------\n";
    
    foo(&foo, 10);
    std::cout<< "--------------\n";
}
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 19:09  [ТС]     Функция должна принять указатель на саму себя #32
Вот же блин. Это не совсем то же самое. У указателя, если его создать, будет свой собственный адрес памяти, отличный от адреса foo. И его при необходимости можно перенаправить, в отличии от &foo, так как непосредственно у foo адрес поменять невозможно.

Может я не очень грамотно выражаюсь, но псевдокод
C++
1
2
3
4
5
6
7
8
foo1(*ptr){}; //Внутри указатель
foo2(*ptr){}; //Внутри указатель
...
*ptr = foo1(ptr);  //Сделали указатель на foo1 и отдали его вовнутрь ;
**ptr; //Подобие разыменования вызывает функцию foo1, а вовнутрь отдается ptr.
 
*ptr = foo2(ptr); //Сделали указатель на foo2 и отдали его вовнутрь;
**ptr; //Подобие разыменования вызывает foo2, а вовнутрь отдается ptr.
Лично мне чем-то отдаленно полиморфизм напоминает.
Притягивать за уши не надо. Решения нет.

Добавлено через 2 минуты
Вы это лучше меня знаете. Я не понимаю, чем я вынуждаю Вас с этим вот спорить.
hoggy
5030 / 2113 / 403
Регистрация: 15.11.2014
Сообщений: 4,797
Завершенные тесты: 1
21.09.2015, 19:22     Функция должна принять указатель на саму себя #33
Цитата Сообщение от daslex Посмотреть сообщение
Я не понимаю, чем я вынуждаю Вас с этим вот спорить.
я с вами и не спорил.
вместо этого я прям у вас на глазах написал код,
который реализует "рекурсивный указатель на функцию".

мой пример-иллюстрация (см #31)
иллюстрирует весь ваш псевдокод.

собственно, вот это главное,
чего вы хотите получить:
C++
1
const auto pFunc = recursivePointer(&foo);
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 19:51  [ТС]     Функция должна принять указатель на саму себя #34
Я не понимаю этого кода, но вижу, что он вообще не похож на показанный псевдокод.
Я сейчас не доказываю, что это не то или что это то. Я не вижу того, что я ожидал. Вопрос не в рекурсивном указателе на функцию. А в функции, вовнутрь которой приходит указатель, который уже показывает на адрес функции, в которую он пришел.

Вовнутрь функции должен передаваться указатель. При этом в разные моменты времени, в зависимости от того, на какую функцию указывает указатель, разыменование указателя приводит к вызову функции, в которую как параметр приходит адрес на начало самой себя. Т.е. если внутри функции просто разыменовывать пришедший в нее указатель, то должна происходить рекурсия.

Вот как-то так вот витиевато все.
Это не мое самолюбие. Я правда не вижу этого у Вас в коде.

Добавлено через 7 минут
C++
1
2
3
foo(pFunc,
foo(foo,
foo(&foo
должно иметь вид (псевдокод).
C++
1
2
3
**ptr; //Обычным разыменованием указателя Вызвал функцию. Если внутри нее разыменовать ptr, то рекурсия
ptr = foo2; //Указатель указывает на другую функцию
**ptr; //Вызвал функцию. Если внутри нее разыменовать ptr, то рекурсия, но уже вот текущей функции
hoggy
5030 / 2113 / 403
Регистрация: 15.11.2014
Сообщений: 4,797
Завершенные тесты: 1
21.09.2015, 20:02     Функция должна принять указатель на саму себя #35
Цитата Сообщение от daslex Посмотреть сообщение
А в функции, вовнутрь которой приходит указатель, который уже показывает на адрес функции, в которую он пришел.
так и есть.

вы ж понимаете, что делает операция взятия адреса?
результатом такой операции является указатель,
который хранит адрес объекта.

смотрите:
C++
1
2
3
// во внутрь foo попадает объект, 
// который является указателем на функцию foo
foo(&foo, 10);
если нужно придержать снаружи,
тогда вот, пожалуйста:

C++
1
2
3
4
5
// --- срисовали
const auto pFunc = recursivePointer(&foo);
 
// чуть позде можно будет запускать:
foo(pFunc, 10);



Цитата Сообщение от daslex Посмотреть сообщение
Вовнутрь функции должен передаваться указатель. При этом в разные моменты времени, в зависимости от того, на какую функцию указывает указатель, разыменование указателя приводит к вызову функции, в которую как параметр приходит адрес на начало самой себя. Т.е. если внутри функции просто разыменовывать пришедший в нее указатель, то должна происходить рекурсия.
так и есть, за исключением того, что разыменовывать не нужно:

C++
1
2
3
4
5
6
7
8
9
10
11
// --- принимает рекурсивный указатель на саму себя
void foo(const recursivePointer& f, const size_t depth)
{
    if(depth == 0)
        return;
    
    std::cout<<"depth recursieve: "<< depth << '\n';
 
    // --- дергает саму себя по указателю
    f(depth - 1);
}
строго говоря,
даже самый обычный указатель на функцию не нужно разыменовывать,
что выполнить запуск функции по указателю.

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

Цитата Сообщение от daslex Посмотреть сообщение
Я правда не вижу этого у Вас в коде.
ну даже если вы не владеете магией шаблонов,
тем менее вы не можете не увидеть,
что в функцию foo передается адрес функции foo.
и что сама функция foo запускает сама себя дергая себя через рекурсивный указатель.

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

он знает, что нужно рекурсивно запускать функцию foo,
потому что я скормил ей указатель на саму себя.

можно было бы скормить что нибудь другое.
но тогда и вызвалось бы тоже что-то другое.
и не было бы рекурсии.

Добавлено через 3 минуты
Цитата Сообщение от daslex Посмотреть сообщение
**ptr; //Обычным разыменованием указателя Вызвал функцию.
нет, так не годится.

технически это конечно можно.
но так не делают.

вот вам простейший встречный вопрос: предположим, нужно вызвать функцию с параметрами.
пускай там будет два инта.
и как вы эти параметры передадите?

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

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

C++
1
2
3
4
5
6
7
8
9
10
void foo(const recursivePointer& f, const size_t depth)
{
    if(depth == 0)
        return;
    
    std::cout<<"depth recursieve: "<< depth << '\n';
 
    // --- вызвать саму себя, передав явный дополнительный аргумент
    f(depth - 1);
}
но ещё повторюсь:
это уже вопросы дизайна.
этакая косметика.
сделать то можно по всякому.
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 20:18  [ТС]     Функция должна принять указатель на саму себя #36
глупый вопрос.
если pFunc это указатель
Цитата Сообщение от hoggy Посмотреть сообщение
const auto pFunc = recursivePointer(&foo);
то почему я не могу применить к нему cout ?

Добавлено через 2 минуты

Не по теме:

я не буду делать акцент на разыменовании для вызова. Это больше было написано как для "импульса к действию", а не действительная потребность.

hoggy
5030 / 2113 / 403
Регистрация: 15.11.2014
Сообщений: 4,797
Завершенные тесты: 1
21.09.2015, 20:32     Функция должна принять указатель на саму себя #37
Цитата Сообщение от daslex Посмотреть сообщение
если pFunc это указатель
Цитата Сообщение от daslex Посмотреть сообщение
то почему я не могу применить к нему cout ?
потому что я не заложил в него такую возможность.

ещё он не умеет делать инкремент, или сравнение.
он вообще ничего не умеет, кроме того,
что вы озвучили в первоначальной задаче.

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

но нужно чутка понимать шаблоны и type erasure.
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 20:40  [ТС]     Функция должна принять указатель на саму себя #38
А с каких пор в указатели можно закладывать возможности?
Указатели, о которых говор я - встроенный тип данных, такой же тип как, например int.
Насколько мне известно, в такие типы свои возможности заложить невозможно.
hoggy
5030 / 2113 / 403
Регистрация: 15.11.2014
Сообщений: 4,797
Завершенные тесты: 1
21.09.2015, 20:55     Функция должна принять указатель на саму себя #39
Цитата Сообщение от daslex Посмотреть сообщение
А с каких пор в указатели можно закладывать возможности?
Указатели, о которых говор я - встроенный тип данных, такой же тип как, например int.
Насколько мне известно, в такие типы свои возможности заложить невозможно.
у вас была задача - поиметь возможность пнуть самого себя рекурсивно через указатель на функцию.
я предоставил вам решение, которое позволяет это сделать.

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

но возможным это становится благодаря некой обертке:
C++
1
const auto pFunc = recursivePointer(&foo);
которая выполняет некие магические танцы с бубнами,
что бы обмануть "вечную рекурсию".

и это - красноречивый пример идеалогии языка с++ в действии:
способность расширять свои возможности за счет кода,
написанного на нем самом.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.09.2015, 21:15     Функция должна принять указатель на саму себя
Еще ссылки по теме:

Написать функцию, которая принимает указатель на переменную и присваивает ей модуль самой себя. C++
C++ Перемножить матрицу на саму себя
Указатель в списке ссылается на себя, а не на следующий элемент C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
21.09.2015, 21:15  [ТС]     Функция должна принять указатель на саму себя #40
Всё, что в class мне неизвестно, следовательно непонятно в принципе.
typedef - фиг с ним, синоним.

в mCaller что-то записывается, только что непонятно. Также непонятно что символизирует название mCaller. Что-то типа "Кнопка спуска"?
Цитата Сообщение от hoggy Посмотреть сообщение
mCaller( std::bind(v, v, std:laceholders::_1)
Непонятно. Похоже на функцию без типа, только не понятно что это на самом деле и почему типа не видно.
Цитата Сообщение от hoggy Посмотреть сообщение
recursivePointer(const functor& v)
* * * * :mCaller(v)
* * {}
Остальное тоже внутри класса непонятно, но для начала понять вышеуказанное мне не помешало бы.
Yandex
Объявления
21.09.2015, 21:15     Функция должна принять указатель на саму себя
Ответ Создать тему
Опции темы

Текущее время: 03:42. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru