Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
outoftime
║XLR8║
723 / 623 / 78
Регистрация: 25.07.2009
Сообщений: 3,128
Записей в блоге: 5
#1

Анонимный объект по аналогии с анонимной функцией (lambda) - C++

03.01.2014, 19:18. Просмотров 506. Ответов 12
Метки нет (Все метки)

Приведу вот такой пример:
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
#include <iostream>
#include <vector>
#include <algorithm>
 
class Generator
{
public:
    Generator() : i(1) { }
 
    const int &operator() ()
    {
        return factorial(i++);
    }
private:
    const int factorial(const int &n)
    {
        if (n == 1) return 1;
        return n * factorial(n - 1);
    }
    int i;
};
 
int main()
{
    const int n = 10;
    std::vector<int> v(n);
    std::generate(v.begin(), v.end(), Generator());
    std::cout << std::accumulate(v.begin(), v.end(), 0);
}
После этого кода я задумался а нельзя ли сделать тоже с использованием анонимного вызываемого объекта (функтора) сохраняя его внутренне состояние?

Добавлено через 59 минут
Ничего кроме как держать состояние объекта в отдельной области видимости не могу придумать...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
#include <algorithm>
 
int main()
{
    const int n = 10;
    std::vector<int> v(n);
    {
        int i = 1;
        std::function<int(int)> factorial = [&factorial](const int &n){
            return n == 1 ? 1 : n * factorial(n - 1);
        };
        auto generator = [&](){ return factorial(i++); };
        std::generate(v.begin(), v.end(), generator);
    }
    std::cout << std::accumulate(v.begin(), v.end(), 0);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.01.2014, 19:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Анонимный объект по аналогии с анонимной функцией (lambda) (C++):

Ссылка на объект, возвращаемый функцией - C++
Безопасно ли подобное? typedef std::vector&lt; string &gt; vec; vec someFoo(); vec someBoo() { // что-то делаем vec &amp; x =...

Что вернуть по ссылке, если объект функцией поиска не найден? - C++
Здравствуйте всем! Имеется проблема: приведенная ниже функция ищет элемент (объект класса TreeNode) в бинарном дереве (объект класса...

Почему код окружен анонимной функцией? - JavaScript
Добрый день, Я скачал математическую библиотеку, код которой окружён анонимной функцией, т.е. (function () { //код функций,...

Какую роль играет анонимный объект в системе маршрутизации? - C# ASP.NET
Добрый день. Разъясните пожалуйста один момент в написании маршрутов. Чёт я не въехал в одну вещь. Разбирался, но чуть голову не сломал....

Сконструировать \lambda-вызов и вычислить его значение Lambda - Lisp
Задание Для выражения из таблицы согласно номеру варианта сконструировать \lambda - вызов и вычислить его значение. Присваивать...

Как добавить анонимный тип в объект не на этапе компиляции, а на этапе выполнения программы? Надо для routes.MapRoute - C# ASP.NET
В приложении ASP.NET MVC у меня есть xml файл с маршрутами типа: &lt;route url=&quot;Home/{par1}/{par2}&quot; controller=&quot;Home&quot; action=&quot;MainPage&quot;...

12
gray_fox
What a waste!
1536 / 1241 / 71
Регистрация: 21.04.2012
Сообщений: 2,608
Завершенные тесты: 3
03.01.2014, 19:21 #2
outoftime, попробуй, в чём проблема: http://ideone.com/NkaSvC .
1
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,498
Записей в блоге: 11
03.01.2014, 19:25 #3
Okay, а где анонимность?
2
outoftime
║XLR8║
723 / 623 / 78
Регистрация: 25.07.2009
Сообщений: 3,128
Записей в блоге: 5
03.01.2014, 20:38  [ТС] #4
Вот то, что я, примерно, хочу:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
 
int main()
{
    const int n = 10;
    std::vector<int> v(n);
    auto generator = [](){
        int i = 1;
 
        std::function<int(int)> factorial = [&factorial](const int &n){
            return n < 2 ? 1 : n * factorial(n - 1);
        };
        auto increment = [](int &i) { return i++; };
 
        return std::bind(factorial, std::bind(increment, i));
    };
    std::generate(v.begin(), v.end(), generator());
    std::cout << std::accumulate(v.begin(), v.end(), 0);
}
Добавлено через 1 минуту
Код естественно не рабочий. Но идею отображает полностью.

P.S. он компилируется (:

Добавлено через 4 минуты
Я так понимаю что
Цитата Сообщение от outoftime Посмотреть сообщение
int i = 1;
удаляется после вызова generator и при вызове factorial идет обращение к недоступной области памяти, и обойти это можно используя динамическое управление памятью.

Добавлено через 1 минуту
gray_fox, Dmitriy_M, как я писал выше я не хочу явно объявлять класс.

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

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

Добавлено через 5 минут
Остановился на варианте со структурой, т.к. она максимально проста, позволяет сохранять внутреннее состояние, может быть использована в качестве функтора и она не засоряет общее пространство имен.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
#include <algorithm>
 
int main()
{
    const int n = 10;
    std::vector<int> v(n);
    typedef struct {
        int i = 1;
        int factorial(const int &n) {
            return n < 2 ? 1 : n * this->factorial(n - 1);
        }
        int operator()() {
            return this->factorial(this->i++);
        }
    } generator;
    std::generate(v.begin(), v.end(), generator());
    std::cout << std::accumulate(v.begin(), v.end(), 0);
}
Добавлено через 24 минуты
Как подсказал мне мой друг, можно еще использовать статическую переменную, тогда код можно переписать где-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
#include <algorithm>
 
int main()
{
    const int n = 10;
    std::vector<int> v(n);
    std::generate(v.begin(), v.end(),
                  [](){
                        static int i = 1;
 
                        const std::function<int(const int&)> factorial = 
                            [&factorial](const int &n) {
                                return n < 2 ? 1 : n * factorial(n - 1);
                            };
 
                        return factorial(i++);
                  });
    std::cout << std::accumulate(v.begin(), v.end(), 0);
}
0
gray_fox
What a waste!
1536 / 1241 / 71
Регистрация: 21.04.2012
Сообщений: 2,608
Завершенные тесты: 3
03.01.2014, 21:41 #5
outoftime, я так понял тебе нужен список захвата:
C++
1
2
3
4
int i = 1;
auto generator = [i] () {
   // ...
};
1
Tulosba
:)
Эксперт С++
4619 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
03.01.2014, 21:43 #6
gray_fox, я так понял, ему хотелось максимально локально разместить генератор. Чтобы всё в одном месте, без внешних переменных.
1
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,498
Записей в блоге: 11
03.01.2014, 21:50 #7
Цитата Сообщение от outoftime Посмотреть сообщение
Сейчас задался вопросом о том можно ли вообще обращаться с функциями, в том числе lambda как с объектами, в плане выделения памяти под их внутреннее состояние.
Внутреннее состояние функции храниться в стеке.
Цитата Сообщение от outoftime Посмотреть сообщение
не хочу явно объявлять класс.
А прием тут объект? Объект это сущность в адресном пространстве, он не обязательно связан с классом(пример использования объекта из Python в программе на C/C++)
1
outoftime
║XLR8║
723 / 623 / 78
Регистрация: 25.07.2009
Сообщений: 3,128
Записей в блоге: 5
04.01.2014, 02:46  [ТС] #8
Цитата Сообщение от Tulosba Посмотреть сообщение
я так понял, ему хотелось максимально локально разместить генератор. Чтобы всё в одном месте, без внешних переменных.
gray_fox, Да да да (:

Dmitriy_M, Ну так вот я и хочу создать объект без его описания, т.е. без класса. В моем случае подходят как вариант со структурой так и со статической переменной. Правда структура более щадящая к памяти и вообще вариант получше, только вот мне бы хотелось создать инстанс анонимного класса. К примеру на javascript это было-бы где-то так:
Javascript
1
2
3
4
5
6
var generator = function(){
    var i = 1,
        factorial = function(n){ return n < 2 ? 1 : factorial(n-1) * n; };
 
    return factorial(i++);
};
Но на C++ я не нашел как сделать это в чистом виде. Если у кого есть соображения, не считая уже упомянутых выше, буду признателен если отпишитесь.
0
gray_fox
What a waste!
1536 / 1241 / 71
Регистрация: 21.04.2012
Сообщений: 2,608
Завершенные тесты: 3
04.01.2014, 13:50 #9
Цитата Сообщение от Tulosba Посмотреть сообщение
gray_fox, я так понял, ему хотелось максимально локально разместить генератор. Чтобы всё в одном месте, без внешних переменных.
Тогда никак, насколько я знаю; можно подождать С++14, там обещают определение новых переменных прямо в списке захвата )
0
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,498
Записей в блоге: 11
04.01.2014, 14:20 #10
Кликните здесь для просмотра всего текста

Цитата Сообщение от outoftime Посмотреть сообщение
gray_fox, Да да да (:

Dmitriy_M, Ну так вот я и хочу создать объект без его описания, т.е. без класса. В моем случае подходят как вариант со структурой так и со статической переменной. Правда структура более щадящая к памяти и вообще вариант получше, только вот мне бы хотелось создать инстанс анонимного класса. К примеру на javascript это было-бы где-то так:
Javascript
1
2
3
4
5
6
var generator = function(){
    var i = 1,
        factorial = function(n){ return n < 2 ? 1 : factorial(n-1) * n; };
 
    return factorial(i++);
};
Но на C++ я не нашел как сделать это в чистом виде. Если у кого есть соображения, не считая уже упомянутых выше, буду признателен если отпишитесь.

А где здесь объект и ОО в целом?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <functional>
 
int main() {
 
    std::function<int()> fun = []()
    {
     int k = 4;
     std::function<int (int)> factorial = [&] (int i) 
     { 
        return (i == 1) ? 1 : i * factorial(i - 1); 
     };
     return factorial(k++);
    };
    std::cout<<fun()<<std::endl;
 
    return 0;
}
Почти чистая функциональщина.
0
outoftime
║XLR8║
723 / 623 / 78
Регистрация: 25.07.2009
Сообщений: 3,128
Записей в блоге: 5
04.01.2014, 14:33  [ТС] #11
gray_fox, яссно

Dmitriy_M, Твой вариант не совсем подходит, т.к. k должен быть статическим, т.е. следующий код должен давать факториалы 4!, 5!, 6! и 7!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <functional>
 
int main() {
 
    std::function<int()> fun = []()
    {
     int k = 4;
     std::function<int (int)> factorial = [&] (int i)
     {
        return (i == 1) ? 1 : i * factorial(i - 1);
     };
     return factorial(k++);
    };
    for (int i : {1,2,3,4})
        std::cout<<fun()<<std::endl;
 
    return 0;
}
А вывод будет 4! все время, т.к. k создается каждый раз новый при вызове fun
0
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,498
Записей в блоге: 11
04.01.2014, 14:41 #12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <functional>
 
int main() {
 
    std::function<int(int)> fun = [](int k)
    {
 
     std::function<int (int)> factorial = [&] (int i)
     {
        return (i == 1) ? 1 : i * factorial(i - 1);
     };
     return factorial(k++);
    };
    for (int i : {1,2,3,4,5})
        std::cout<<fun(i)<<std::endl;
 
    return 0;
}
Добавлено через 5 минут
С использованием побочных эффектов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <functional>
 
int main() {
 
    std::function<int()> fun = []()
    {
    static int k = 1;
 
     std::function<int (int)> factorial = [&] (int i)
     {
        return (i == 1) ? 1 : i * factorial(i - 1);
     };
     return factorial(k++);
    };
    for (int i : {1,2,3,4,5})
        std::cout<<fun()<<std::endl;
 
    return 0;
}
0
outoftime
║XLR8║
723 / 623 / 78
Регистрация: 25.07.2009
Сообщений: 3,128
Записей в блоге: 5
04.01.2014, 14:48  [ТС] #13
Цитата Сообщение от outoftime Посмотреть сообщение
Если у кого есть соображения, не считая уже упомянутых выше
Видимо эту часть надо было выделить жирным...
0
04.01.2014, 14:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.01.2014, 14:48
Привет! Вот еще темы с ответами:

Графический объект движение которого задан функцией - C++ Builder
Написать программу которая строит графический объект движение которого задан функцией, вот с силка, здесь программа с моей функцией....

Как связывается целевой объект с функцией-обработчиком, если использовать модель событий W3C DOM уровня 2? - JavaScript
Привет. 1. Если я пишу function func(){...}; document.getElementById(&quot;red&quot;).onclick=func; , то свойство onclick станет ссылаться не...

Вызов в анонимной функции - JavaScript
Подскажите пожалуйста почему _render вызывается внутри анонимной функции в setInterval? function Clock(options) { this._template =...

Запуск анонимной функции - JavaScript
Hi all! Что можно сделать если есть функция $(window).load(function(){//тут какая-то логика я работаю с аяксом и мне...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru