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

Создать класс, в котором можно сохранить любой вызываемый объект или функцию - C++

Восстановить пароль Регистрация
 
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
11.08.2014, 14:27     Создать класс, в котором можно сохранить любой вызываемый объект или функцию #1
Возникла идея создать класс, в котором можно сохранить любой вызываемый объект или функцию. Что то наподобие std::function, но только не параметризирован, с использованием технологии Type Erasure. Вот такой первый набросок получился (естественно не рабочий):
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <boost/type_traits/function_traits.hpp>
 
class function_wrapper
{
   struct base_holder
   {
      virtual ~base_holder() {}
 
      template <typename... Args>
      return_type call(Args&&... args) const = 0;
   };
 
   template <typename F>
   struct func_holder : base_holder
   {
      F f;
      func_holder(F&& f_) : f(std::move(f_)) {}
 
      template <typename... Args>
      return_type call(Args&&... args) const
      {
         return f(std::forward<Args>(args)...);
      }
   };
 
   std::shared_ptr<base_holder> holder;
 
public:
   template <typename T>
   explicit function_wrapper(T&& t) : holder(new func_holder<T>(std::forward<T>(t)))
   {
      //этот тип надо както сохранить и использовать в качестве возвращаемого
      //типа в operator()
      typedef typename boost::function_traits<T>::result_type return_type;
   }
 
   template <typename... Args>
   return_type operator ()(Args&&... args) const
   {
      return holder->call(std::forward<Args>(args)...);
   }
};
 
////////////////////////////////////////////////////////////////////////////////
 
void foo1(const std::string& s, int val)
{
   std::cout << s << " " << val << "\n";
}
 
int foo2(const std::string& s, int val)
{
   std::cout << s << "\n";
   return val;
}
 
int main()
{
   std::vector<function_wrapper> fw;
   fw.push_back(function_wrapper(foo1));
   fw.push_back(function_wrapper(foo2));
 
   std::cout << fw[0]("return void", 100);
   auto val = fw[1]("return int", 10);
   std::cout << val << "\n";
 
   std::cout << "Bye... :-) \n\n";
   return 0;
}
В первую очередь интересует как можно сохранить возвращаемый тип ф-ции для вызова operator(). Еще есть идея хранить в func_holder тот же самый std::function, но снова возникает проблема определения возвращаемого типа. Ну и вообщем, какие у кого мнения по данному вопросу будут?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.08.2014, 14:27     Создать класс, в котором можно сохранить любой вызываемый объект или функцию
Посмотрите здесь:

C++ Создать класс, в котором реализовать функции для работы с одномерными массивами
C++ Создать базовый класс Array, в котором определите поле-массив подходящего типа
C++ Создать любой класс. Реализовать конструктор, деструктор, продемонстрировать работу
C++ Создать класс, который определяет можно ли по введенным значениям построить треугольник, и если можно, то какой
C++ Можно-ли наследовать класс, в котором определен объект текущего класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.08.2014, 14:40     Создать класс, в котором можно сохранить любой вызываемый объект или функцию #2
C++
1
2
3
4
5
6
7
   struct base_holder
   {
      virtual ~base_holder() {}
 
      template <typename... Args>
      return_type call(Args&&... args) const = 0;
   };
Это невозможно, т.к. return_type здесь просто негде узнать и известен он должен быть на этапе компиляции.
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
11.08.2014, 15:09  [ТС]     Создать класс, в котором можно сохранить любой вызываемый объект или функцию #3
Разве только что тогда параметризировать function_wrapper списком всевозможных возврвщаемых типов и возвращать какой нибудь any или variant.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.08.2014, 15:23     Создать класс, в котором можно сохранить любой вызываемый объект или функцию #4
DiffEreD, Ну да, возможно. Буст ведь тоже не идиоты пишут, а т.к. any не имеет conversion оператора, но имеет шаблонные функции вида any_cast, делаем вывод, что такой трюк реализовать невозможно.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
11.08.2014, 16:53     Создать класс, в котором можно сохранить любой вызываемый объект или функцию #5

Не по теме:

Цитата Сообщение от DiffEreD Посмотреть сообщение
технологии Type Erasure
type erasure это метод, прием, идиома, но не технология



Добавлено через 6 минут
по теме:
как вариант навешивать callback в который будет пихатся результат
Абстракция вызова функции
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,283
11.08.2014, 21:30     Создать класс, в котором можно сохранить любой вызываемый объект или функцию #6
Цитата Сообщение от DiffEreD Посмотреть сообщение
. Что то наподобие std::function, но только не параметризирован, с использованием технологии Type Erasure
А зачем? Я вот не понимаю, это что-то сродни мазохизму что-ли? Ну, т.е. нравится, когда ошибки происходят в рантайме, а не в компайл-тайм?
Yandex
Объявления
11.08.2014, 21:30     Создать класс, в котором можно сохранить любой вызываемый объект или функцию
Ответ Создать тему
Опции темы

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