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

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

Войти
Регистрация
Восстановить пароль
 
rikimaru2013
C++ Game Dev
2429 / 1123 / 240
Регистрация: 30.11.2013
Сообщений: 3,673
#1

Сравнение std::function с необходимым каллбеком - C++

01.07.2016, 16:55. Просмотров 342. Ответов 12
Метки нет (Все метки)

Добрый день,

из - за захвата this не работает проверка каллбека на корректность - onAppStart3 - как с этим бороться -

Кликните здесь для просмотра всего текста
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
74
#include <iostream>
#include <functional>
using namespace std;
 
//////////////////////////////////////////////////////////////////////////
class IFoo
{
public:
    virtual void onAppStarted( int, int ) = 0;
};
//////////////////////////////////////////////////////////////////////////
template <typename T>
struct FunctionTypeDeduction;
 
template<class ClassType, class ReturnType, class... Args>
struct FunctionTypeDeduction< ReturnType( ClassType::* )( Args... ) >
{
    using type                                  = ReturnType( *)( Args... );
    using functorType                           = std::function<ReturnType( Args... ) >;
};
//////////////////////////////////////////////////////////////////////////
class SubcribeSystem
{
public:
    using tSomeMethodType                       = FunctionTypeDeduction< decltype( &IFoo::onAppStarted ) >::type;
    using tSomeMethodCallback                   = FunctionTypeDeduction< decltype( &IFoo::onAppStarted ) >::functorType;
 
public:
    void subribeOnSomeMethod( const tSomeMethodCallback& arr )
    {
        arr( 3, 19 );
    }
};
#define SUBCRIBE_FOR_SOMEMETHOD( eventsObj, lambda )                    \
    do                                                                  \
    {                                                                   \
        SubcribeSystem::tSomeMethodType const func_ptr = lambda;        \
        eventsObj.subribeOnSomeMethod( lambda );                        \
    }                                                                   \
    while(false);                                                       
//////////////////////////////////////////////////////////////////////////
class Bar
{
public:
    void fn( SubcribeSystem& events )
    {
        auto onAppStart = []( int width, int height )
        {
            cout << width << " " << height << endl;
        };
        auto onAppStart2 = []( bool width, int height )
        {
            cout << width << " " << height << endl;
        };
        auto onAppStart3 = [this]( int width, int height )
        {
            cout << width << " " << height << endl;
            someOtherMethod( width );
        };
        SUBCRIBE_FOR_SOMEMETHOD( events, onAppStart );      // expect all ok    
        //SUBCRIBE_FOR_SOMEMETHOD( events, onAppStart2 );   // expect error cause bool first param  
        SUBCRIBE_FOR_SOMEMETHOD( events, onAppStart3 );     // expect all ok, but not !!!
    }
    void someOtherMethod( int x )
    {
        cout << "processed callback " << x << endl;
    }
};
int main()
{
    Bar bar;
    SubcribeSystem sub;
    bar.fn( sub );
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.07.2016, 16:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сравнение std::function с необходимым каллбеком (C++):

Какая реализация лучше? std::pointer_to_binary_function vs std::function - C++
Какая реализация (set_p или set_f) лучше /современнее / эффективнее ? pointer_to_binary_function в С++11 объявлен как deprecated. Правильно...

Использование std::function в std::thread - C++
Нужно вызвать function fnc в новом потоке. Как сделать? function &lt;void(vector&lt;char&gt;)&gt; fnc; void test(vector&lt;char&gt; data) { for...

Std::function and std::vector - C++
Как положить обёртки в вектор? Не используя библиотеку boost. function&lt;void(int)&gt; first_func() = one(); function&lt;void(int)&gt;...

Объединение std::function в контейнер - C++
Во многих ЯП есть делегаты. В случае с С++ у нас в распоряжении есть std::function, им можно обернуть как и обычные функции, так и лямбды с...

Std::function на шаблонную функцию - C++
Здравствуйте :) Делаю такую вещь: template &lt;typename T1, typename T2&gt; typename std::common_type&lt;T1,T2&gt;::type func(T1 val1, T2 val2) ...

Вызов const метод std::function - C++
Добрый день, #include &lt;functional&gt; #include &lt;string&gt; #include &lt;iostream&gt; using namespace std; class Foo { ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
nonedark2008
903 / 642 / 131
Регистрация: 28.07.2012
Сообщений: 1,733
01.07.2016, 17:20 #2
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
C++
1
2
3
4
5
6
7
#define SUBCRIBE_FOR_SOMEMETHOD( eventsObj, lambda )                    \
    do                                                                  \
    {                                                                   \
        SubcribeSystem::tSomeMethodType const func_ptr = lambda;        \
        eventsObj.subribeOnSomeMethod( lambda );                        \
    }                                                                   \
    while(false);
Не думаю, что замыкание можно так запросто скастить к обычному указателю на функцию.
Попробуй вместо tSomeMethodType использовать tSomeMethodCallback.
rikimaru2013
C++ Game Dev
2429 / 1123 / 240
Регистрация: 30.11.2013
Сообщений: 3,673
01.07.2016, 17:22  [ТС] #3
nonedark2008, тогда будет проблема от которой я бегу
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <functional>
using namespace std;
 
int main()
{
    std::function<void( float, int )> a;
    a = []( int d, int r )
    {
        cout << d << " " << r << endl;
    };
 
    a( 15.7, 15 );
}
nonedark2008
903 / 642 / 131
Регистрация: 28.07.2012
Сообщений: 1,733
01.07.2016, 18:38 #4
rikimaru2013, а в чем собственно проблема?
В совсем неявном приведении типов?
rikimaru2013
C++ Game Dev
2429 / 1123 / 240
Регистрация: 30.11.2013
Сообщений: 3,673
01.07.2016, 18:50  [ТС] #5
nonedark2008, да, и если - что-то не то - ошибка в недрях и попробуй найти кто именно не прав...
nonedark2008
903 / 642 / 131
Регистрация: 28.07.2012
Сообщений: 1,733
01.07.2016, 18:55 #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
rikimaru2013, ну тогда что-то такое:
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
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <functional>
#include <type_traits>
using namespace std;
 
//////////////////////////////////////////////////////////////////////////
class IFoo
{
public:
    virtual void onAppStarted(int, int) = 0;
};
//////////////////////////////////////////////////////////////////////////
 
template <typename T>
struct FunctionTypeDeduction : public FunctionTypeDeduction<decltype(&T::operator())>  
{};
//////////////////////////////////////////////////////////////////////////
 
template<class ClassType, class ReturnType, class... Args>
struct FunctionTypeDeduction< ReturnType(ClassType::*)(Args...) >
{
    using type = ReturnType(*)(Args...);
    using functorType = std::function<ReturnType(Args...) >;
};
//////////////////////////////////////////////////////////////////////////
 
template<class ClassType, class ReturnType, class... Args>
struct FunctionTypeDeduction< ReturnType(ClassType::*)(Args...) const> : FunctionTypeDeduction< ReturnType(ClassType::*)(Args...)>
{};
//////////////////////////////////////////////////////////////////////////
 
class SubcribeSystem
{
public:
    using tSomeMethodType = FunctionTypeDeduction< decltype(&IFoo::onAppStarted) >::type;
    using tSomeMethodCallback = FunctionTypeDeduction< decltype(&IFoo::onAppStarted) >::functorType;
 
public:
    void subribeOnSomeMethod(const tSomeMethodCallback& arr)
    {
        arr(3, 19);
    }
};
#define SUBCRIBE_FOR_SOMEMETHOD( eventsObj, lambda )                    \
    do                                                                  \
    {                                                                   \
        static_assert(is_same<SubcribeSystem::tSomeMethodType, FunctionTypeDeduction<decltype(lambda)>::type>::value, "bad type"); \
        SubcribeSystem::tSomeMethodCallback const func_ptr = lambda;    \
        eventsObj.subribeOnSomeMethod( lambda );                        \
    }                                                                   \
    while(false);                                                       
//////////////////////////////////////////////////////////////////////////
class Bar
{
public:
    void fn(SubcribeSystem& events)
    {
        auto onAppStart = [](int width, int height)
        {
            cout << width << " " << height << endl;
        };
        auto onAppStart2 = [](bool width, int height)
        {
            cout << width << " " << height << endl;
        };
        auto onAppStart3 = [this](int width, int height)
        {
            cout << width << " " << height << endl;
            someOtherMethod(width);
        };
        SUBCRIBE_FOR_SOMEMETHOD(events, onAppStart);      // expect ok    
        SUBCRIBE_FOR_SOMEMETHOD(events, onAppStart2);     // expect error
        SUBCRIBE_FOR_SOMEMETHOD(events, onAppStart3);     // expect ok
    }
    void someOtherMethod(int x)
    {
        cout << "processed callback " << x << endl;
    }
};
int main()
{
    Bar bar;
    SubcribeSystem sub;
    bar.fn(sub);
}
Как дедуцировать тип лямбды я честно нарыл в интернете...
rikimaru2013
C++ Game Dev
2429 / 1123 / 240
Регистрация: 30.11.2013
Сообщений: 3,673
01.07.2016, 19:00  [ТС] #7
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Как дедуцировать тип лямбды я честно нарыл в интернете...
А вы честный))) Это приятно слышать )
nonedark2008
01.07.2016, 19:07
  #8

Не по теме:

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
А вы честный))) Это приятно слышать )
Какой-то человек старался решить проблему и в итоге решил. А я должен просто присвоить его заслуги себе?
Тем более это убирает возможные нежелательные вопросы ко мне =)

rikimaru2013
01.07.2016, 19:09  [ТС]
  #9

Не по теме:

nonedark2008, ну благородно) А не могли бы вы еще ссылку на тему с lambda type deduction скинуть в ЛС - а то гуглил не раз и не находил полезное

avgoor
885 / 520 / 112
Регистрация: 05.12.2015
Сообщений: 1,465
01.07.2016, 19:18 #10
rikimaru2013, по стандарту лямбда содержит оператор каста к указателю на функцию, только если она вообще ничего не захватывает.
nonedark2008
903 / 642 / 131
Регистрация: 28.07.2012
Сообщений: 1,733
01.07.2016, 19:19 #11
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
А не могли бы вы еще ссылку на тему с lambda type deduction скинуть в ЛС - а то гуглил не раз и не находил полезное
Собственно тык - ничего сверх научного.
Вся идея в том, что лямбда реализуется через класс с некоторым образом перегруженным оператором ().
Если взять указатель на этот оператор, то его можно дедуцировать как обычный указатель на метод класса.
rikimaru2013
C++ Game Dev
2429 / 1123 / 240
Регистрация: 30.11.2013
Сообщений: 3,673
01.07.2016, 19:24  [ТС] #12
avgoor, та я к указателю привожу поскольку не знал другого выхода выкинуть ошибку в месте вызова - а то при смене "интерфейса каллбека" - вылазят ошибки не в месте вызова, а в недрях
avgoor
885 / 520 / 112
Регистрация: 05.12.2015
Сообщений: 1,465
01.07.2016, 19:38 #13
rikimaru2013, Какие ошибки и где вылазят?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.07.2016, 19:38
Привет! Вот еще темы с ответами:

В std::function передать метод класса - C++
Есть класс MyClass и в нем функция void Func(int). Как правильно объявить переменную function на этот метод? std::function&lt;void...

Сигнатура std::function и прототип метода - C++
Добрый вечер, #include &lt;functional&gt; #include &lt;string&gt; #include &lt;iostream&gt; using namespace std; class A { ...

Std::function для хранения функции класса - C++
class test { public: test() { f = display5; //Как правильно написать? } void setFunction(function&lt;void()&gt; func) { ...

Чем boost::signal отличается от std::function - C++
Чем boost::signal отличается от std::function ?


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
01.07.2016, 19:38
Ответ Создать тему
Опции темы

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