Re[7]: Метод класс как С колбек
От: Evgeny.Panasyuk Россия  
Дата: 09.04.15 22:20
Оценка:
Здравствуйте, sokel, Вы писали:

S>ну а сигнатуру то всё равно нужно отдельным параметром передавать.


Можно выводить — если конечно то что выведется устроит. Но вывод не всегда возможен, например с шаблонами или перегрузкой — так что тут зависит от ситуации, думаю явная сигнатура предпочтительней.

S>Кстати, optional не съест noncopyable.


Почему? Судя по документации — должен: 1, 2.

Это как раз std::function noncopyable не съест — особенности type-erasure (тут как раз нужен специальный тип a-la move_function).
Re[2]: Метод класс как С колбек
От: AHOHUM  
Дата: 10.04.15 05:57
Оценка:
Здравствуйте, beyv, Вы писали:

B>Здравствуйте, AHOHUM, Вы писали:


B>Рекомендую FastDelegate, сам много лет использую для колбеков всех мастей.

B>Желательно прочитать статью чтобы понять как оно работает.

Да, именно про эту статью я и писал выше, тут даже есть перевод её здесь
Автор(ы): Don Clugston
Дата: 27.07.2005
В данной статье предоставлен исчерпывающий материал по указателям на функции-члены, а также приведена реализация делегатов, которые занимают всего две операции на ассемблере.
датированный 2004 годом, замечательная статья, но как уже писал, предполагал, что за прошедшее время могло что-нибудь появиться и в стандарте.
Re[3]: Метод класс как С колбек
От: Zenden Россия  
Дата: 10.04.15 06:17
Оценка:
Здравствуйте, AHOHUM, Вы писали:

AHO>Здравствуйте, beyv, Вы писали:


B>>Здравствуйте, AHOHUM, Вы писали:


B>>Рекомендую FastDelegate, сам много лет использую для колбеков всех мастей.

B>>Желательно прочитать статью чтобы понять как оно работает.

AHO>Да, именно про эту статью я и писал выше, тут даже есть перевод её здесь
Автор(ы): Don Clugston
Дата: 27.07.2005
В данной статье предоставлен исчерпывающий материал по указателям на функции-члены, а также приведена реализация делегатов, которые занимают всего две операции на ассемблере.
датированный 2004 годом, замечательная статья, но как уже писал, предполагал, что за прошедшее время могло что-нибудь появиться и в стандарте.


Разве оно умеет "Метод класс как С колбек" ?
Re[8]: Метод класс как С колбек
От: sokel Россия  
Дата: 10.04.15 09:37
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Это как раз std::function noncopyable не съест — особенности type-erasure (тут как раз нужен специальный тип a-la move_function).


std::function это да, там копирование не выпиливается потому что виртуализируется.

EP>Почему? Судя по документации — должен: 1, 2.


А с boost — ну у меня, видимо, boost старый — 1.55. Но похоже ещё и у bind с move присваиванием проблемы могут быть...
Свой storage для функтора позволяет понизить требование с move-assignable до move-constructible.
Или я что то не так делаю?

#include <iostream>
#include <memory>
#include <boost/optional.hpp>

// примерный optional, присваивание через perfect forward
template<typename T>
struct opt_move_assign {
    ~opt_move_assign() {
        if(constructed)
            reinterpret_cast<T*>(&data)->~T();
    }
    template<typename U>
    opt_move_assign& operator=(U&& x) {
        if(constructed)
            *(reinterpret_cast<T*>(&data)) = std::forward<U>(x);
        else {
            new (&data) T(std::forward<T>(x));
            constructed = true;
        }
        return *this;
    }
    bool constructed = false;
    typename std::aligned_storage<sizeof(T)>::type data;
};
// примерный optional, присваивание не используется
template<typename T>
struct opt_move_construct {
    ~opt_move_construct() {
        if(constructed)
            reinterpret_cast<T*>(&data)->~T();
    }
    template<typename U>
    opt_move_construct& operator=(U&& x) {
        if(constructed) {
            constructed = false;
            reinterpret_cast<T*>(&data)->~T();
        }
        new (&data) T(std::forward<T>(x));
        constructed = true;
        return *this;
    }
    bool constructed = false;
    typename std::aligned_storage<sizeof(T)>::type data;
};

template<template<class> class Storage, class F>
void test(F&& f) {
    using store_type = std::decay<F>::type;
    Storage<store_type> x;
    x = std::forward<F>(f);
}


struct foo {
    void bar() {}
};

int main() {
    // вот это ок, компилится
    test<opt_move_assign>(std::make_unique<int>(111));
    test<opt_move_construct>(std::make_unique<int>(111));

    // вот это уже нет (boost 1.55)
    // test<boost::optional>(std::make_unique<int>(111));

    // а вот тут уже bind, вылезает copy tuple
    // test<opt_move_assign>(std::bind(&foo::bar, std::make_unique<foo>()));
    // хотя через move-construct всё ok
    test<opt_move_construct>(std::bind(&foo::bar, std::make_unique<foo>()));

    // ну как и в предыдушем варианте, тоже беда...
    // test<boost::optional>(std::bind(&foo::bar, std::make_unique<foo>()));
    return 0;
}
Re[9]: Метод класс как С колбек
От: sokel Россия  
Дата: 10.04.15 11:21
Оценка:
Здравствуйте, sokel, Вы писали:

S>Но похоже ещё и у bind с move присваиванием проблемы могут быть...

S>Свой storage для функтора позволяет понизить требование с move-assignable до move-constructible.
S>Или я что то не так делаю?

А, ну собственно по стандарту никто и не требует от bind быть MoveAssignable:

The return type shall satisfy the requirements of MoveConstructible. If all of FD and TiD
satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements
of CopyConstructible. [ Note: This implies that all of FD and TiD are MoveConstructible. — end
note ]

Re[4]: Метод класс как С колбек
От: beyv  
Дата: 10.04.15 11:39
Оценка:
Здравствуйте, Zenden, Вы писали:

Z>Разве оно умеет "Метод класс как С колбек" ?


Да, умеет (если вставить недостающие буквы в "Метод класс как С колбек" )

там есть примеры в FastDelegateDemo.cpp

примерно так

using namespace fastdelegate;

// Это класс
class CClass {
public:
    // Это метод класса
    int Function(int num, char *str);
};

int main(void){

    // Обьявляете тип делегата (параметр1, параметр2, тип результата)
    typedef FastDelegate2<int, char *, int> FunctionDelegate;

    // Создаете класс
    CClass a();

    // "deleg" - переменная-колбек, цепляем на неё метод класса
    FunctionDelegate deleg = MakeDelegate(&a, &CClass::Function);

    // вызываем метод класса как простую функцию
    int ret = deleg(5, "foo"); 
}
Re[5]: Метод класс как С колбек
От: Zenden Россия  
Дата: 10.04.15 13:31
Оценка:
Здравствуйте, beyv, Вы писали:

B>Здравствуйте, Zenden, Вы писали:


Z>>Разве оно умеет "Метод класс как С колбек" ?


B>Да, умеет (если вставить недостающие буквы в "Метод класс как С колбек" )


B>там есть примеры в FastDelegateDemo.cpp


Неа, не умеет. Задачу автора (и мою) не решает.
У fastdelegate просто перегружен operator(), а нужен простой указатель на фукнцию.
Re[6]: Метод класс как С колбек
От: beyv  
Дата: 10.04.15 14:07
Оценка:
Здравствуйте, Zenden, Вы писали:

Z>Неа, не умеет. Задачу автора (и мою) не решает.

Z>У fastdelegate просто перегружен operator(), а нужен простой указатель на фукнцию.

Даа, умеет. Задача автора: "Метод класс как С колбек" а не "простой указатель на фукнцию"
Переменную "FunctionDelegate deleg" (из примера) можно использовать как угодно — брать адрес, передавать как параметр, запускать в космос...
Если "задача" у вас поизвращатся и пытатся изобрести велосипед, ну чтож...
Re[7]: Метод класс как С колбек
От: Zenden Россия  
Дата: 10.04.15 14:40
Оценка:
Здравствуйте, beyv, Вы писали:

B>Здравствуйте, Zenden, Вы писали:


Z>>Неа, не умеет. Задачу автора (и мою) не решает.

Z>>У fastdelegate просто перегружен operator(), а нужен простой указатель на фукнцию.

B>Даа, умеет. Задача автора: "Метод класс как С колбек" а не "простой указатель на фукнцию"

B>Переменную "FunctionDelegate deleg" (из примера) можно использовать как угодно — брать адрес, передавать как параметр, запускать в космос...
B>Если "задача" у вас поизвращатся и пытатся изобрести велосипед, ну чтож...

На этом, как вы говорите, "извращении" немало библиотек построено — например ATL, WTL.
Задача дана вполне конкретная, общего решения так и не предложено.
fastdelegate хорошая вещь, я ее использую в своих проектах, но в данном случае она приведена не к месту.
Отредактировано 10.04.2015 14:44 Zenden . Предыдущая версия . Еще …
Отредактировано 10.04.2015 14:42 Zenden . Предыдущая версия .
Отредактировано 10.04.2015 14:41 Zenden . Предыдущая версия .
Re[7]: Метод класс как С колбек
От: Evgeny.Panasyuk Россия  
Дата: 10.04.15 14:41
Оценка:
Здравствуйте, beyv, Вы писали:

B>Даа, умеет. Задача автора: "Метод класс как С колбек" а не "простой указатель на фукнцию"


Прочитай изначальное сообщение, а не только его заголовок.
Re[8]: Метод класс как С колбек
От: beyv  
Дата: 10.04.15 15:54
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, beyv, Вы писали:


B>>Даа, умеет. Задача автора: "Метод класс как С колбек" а не "простой указатель на фукнцию"


EP>Прочитай изначальное сообщение, а не только его заголовок.


Прочитайте исходные код FastDelegate, прежде чем умничать.
Основная загвоздка у ТС получения доступа к полям класса в теле колбека или где там.

Пожалуйста, получите от делегата указатель "This", приведите его к классу и вот вам класс


#include "stdafx.h"
#include "FastDelegate.h"

using namespace fastdelegate;

// Это класс
class CClass {
protected:
    char *m_name;
public:
    CClass(char *name) : m_name(name) {};

    // Это метод класса
    int Function(int num, char *str) {
        printf("In Function in %s. Num=%d, str = %s\n", m_name, num, str); return -1;
    }

};

int _tmain(int argc, _TCHAR* argv[])
{
    typedef FastDelegate2<int, char *, int> FunctionDelegate;
    // Создаете класс
    CClass a("Base A");

    // "deleg" - переменная-колбек
    FunctionDelegate deleg;

    // цепляем на неё метод класса и можем передать его куда угодно
    deleg = MakeDelegate(&a, &CClass::Function);

    // можем использовать как функцию
    deleg(7, "tr");
    
    // Чуть поизвращаясь, можно получить указатель на сам класс
    const detail::ClosurePtr<int, char *, int>& p = (const detail::ClosurePtr<int, char *, int>&)deleg.GetMemento();
    CClass* ap = (CClass*)p.GetClosureThis();

    // Получили класс со всеми потрохами
    ap->Function(77, "ааааа");

    return 0;
}
Отредактировано 10.04.2015 15:59 beyv . Предыдущая версия .
Re[9]: Метод класс как С колбек
От: Evgeny.Panasyuk Россия  
Дата: 10.04.15 16:09
Оценка:
Здравствуйте, beyv, Вы писали:

B>>>Даа, умеет. Задача автора: "Метод класс как С колбек" а не "простой указатель на фукнцию"

EP>>Прочитай изначальное сообщение, а не только его заголовок.
B>Прочитайте исходные код FastDelegate,

И в чём там принципиальное отличие от std::function в рамках вопроса ТС?

B>прежде чем умничать.


О, вот уже и хамство пошло в ход — классный аргумент, главное универсальный

B>Основная загвоздка у ТС получения доступа к полям класса в теле колбека или где там.

B>Пожалуйста, получите от делегата указатель "This", приведите его к классу и вот вам класс

И что это даст в случае ТС?

AHO>Имеется С библиотека с неизменяемым интерфейсом, одна из функций выглядит так:
AHO>

AHO>typedef void(*Callback)(void * internalState, Data * data);
AHO>void addCallback(void * internalState, Callback * callback);
AHO>

AHO>internalState – сугубо внутренняя структура библиотеки, data – данные получаемые из библиотеки, т.е. никаких void * userData нет.

AHO>Хотелось бы в плюсах 11, чтобы сallback вызывал метод класса. Решение со статическим методом и глобальным this – совсем уж убого.

Эта библиотека принимает только указатель на функцию, и не позволяет прямым способом передать контекст — чем тут поможет этот FastDelegate?
Re[10]: Метод класс как С колбек
От: beyv  
Дата: 10.04.15 16:28
Оценка: :))
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>[/q]

EP>Эта библиотека принимает только указатель на функцию, и не позволяет прямым способом передать контекст — чем тут поможет этот FastDelegate?

В с(++) есть скобочки:

addCallback(void * internalState, (Callback *)хоть-черт-с-ушами);


Для тех (пардон) кто совсем в танке:

FunctionDelegate deleg;
addCallback(void * internalState, (Callback *)&deleg);
Re[10]: Метод класс как С колбек
От: beyv  
Дата: 10.04.15 16:34
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>И в чём там принципиальное отличие от std::function в рамках вопроса ТС?


FastDelegate инкапсулирует в себе и "this" и "метод класса"

EP>О, вот уже и хамство пошло в ход — классный аргумент, главное универсальный


Как и сам язык с++
Re[11]: Метод класс как С колбек
От: Evgeny.Panasyuk Россия  
Дата: 10.04.15 16:40
Оценка:
Здравствуйте, beyv, Вы писали:

EP>>И в чём там принципиальное отличие от std::function в рамках вопроса ТС?

B>FastDelegate инкапсулирует в себе и "this" и "метод класса"

Точно также как и std::function + std::bind, только проблему ТС это никак не решает
Re[11]: Метод класс как С колбек
От: Evgeny.Panasyuk Россия  
Дата: 10.04.15 16:42
Оценка: +2
Здравствуйте, beyv, Вы писали:

EP>>Эта библиотека принимает только указатель на функцию, и не позволяет прямым способом передать контекст — чем тут поможет этот FastDelegate?

B>В с(++) есть скобочки:
B>
B>addCallback(void * internalState, (Callback *)хоть-черт-с-ушами);
B>

B>Для тех (пардон) кто совсем в танке:
B>
B>FunctionDelegate deleg;
B>addCallback(void * internalState, (Callback *)&deleg);
B>


Очевидно что у ТС задача чтобы код работал, без вылетов и UB, а не просто компилировался
Re[12]: Метод класс как С колбек
От: beyv  
Дата: 10.04.15 16:51
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, beyv, Вы писали:


EP>>>И в чём там принципиальное отличие от std::function в рамках вопроса ТС?

B>>FastDelegate инкапсулирует в себе и "this" и "метод класса"

EP>Точно также как и std::function + std::bind, только проблему ТС это никак не решает


Ну вы даете, я вам нарисовал как сделать делегата(колбек) на экземпляр любого класса и любой его метод(хоть с 6 параметрами),

как передать его в "void addCallback(void * internalState, Callback * callback);" вместо "callback"

как извлечь из переданого делегата экземпляр переданого класса и делать с ним что угодно

и это не решает проблему ТС ?
Боюсь даже спрашивать какая ещё тут проблема, кривые руки? непонимание чужого кода?
Re[12]: Метод класс как С колбек
От: beyv  
Дата: 10.04.15 16:56
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Очевидно что у ТС задача чтобы код работал, без вылетов и UB, а не просто компилировался


Чтобы поломать код которым люди пользуются 9 лет со всеми существующими компиляторами надо иметь особое упорство
Re[2]: Метод класс как С колбек
От: Zenden Россия  
Дата: 10.04.15 19:14
Оценка:
Вот один из работающих вариантов:
http://p-nand-q.com/programming/cplusplus/using_member_functions_with_c_function_pointers.html
Re[13]: Метод класс как С колбек
От: Evgeny.Panasyuk Россия  
Дата: 10.04.15 19:44
Оценка:
Здравствуйте, beyv, Вы писали:

EP>>>>И в чём там принципиальное отличие от std::function в рамках вопроса ТС?

B>>>FastDelegate инкапсулирует в себе и "this" и "метод класса"
EP>>Точно также как и std::function + std::bind, только проблему ТС это никак не решает
B>Ну вы даете, я вам нарисовал как сделать делегата(колбек) на экземпляр любого класса и любой его метод(хоть с 6 параметрами),
B>как передать его в "void addCallback(void * internalState, Callback * callback);" вместо "callback"

Этот callback будет использоваться внутри именно как указатель на функцию (то есть будет совершён вызов кода по этому адресу), вместо которого ты пытаешься передать указатель на экземпляр класса FastDelegate.
То есть получается что-то типа: LIVE DEMO
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.