Универсальный указатель на функцию-член класса
От: AkaSaint  
Дата: 06.10.02 10:04
Оценка:
Вопрос: как можно реализовать сабж на чистом С/С++ или в MSVC 7? В Билдере есть очень удобная штука — __closure, с ее помощью можно определить указатель на функцию — член любого класса, лишь бы параметры и возвращаемые значения совпадали (ну и соглашения по вызову). А в MSVC получается, мне еще нужно знать, и какого класса функция.... Помогите пожалуйста.
Re: Универсальный указатель на функцию-член класса
От: Павел Кузнецов  
Дата: 06.10.02 10:10
Оценка:
Здравствуйте AkaSaint, Вы писали:

AS>Вопрос: как можно реализовать сабж на чистом С/С++ или в MSVC 7?


В каком контексте? Решений есть несколько, каждое хорошо на своем месте.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Универсальный указатель на функцию-член класса
От: AkaSaint  
Дата: 06.10.02 22:29
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>Здравствуйте AkaSaint, Вы писали:


AS>>Вопрос: как можно реализовать сабж на чистом С/С++ или в MSVC 7?


ПК>В каком контексте? Решений есть несколько, каждое хорошо на своем месте.


Контекст такой: есть класс — окно со скином, он предоставляет возможность тому, кто его использует, устанавливать свои обработчики сообщений, типа OnClose.
Re[3]: Универсальный указатель на функцию-член класса
От: Ed.ward Россия  
Дата: 07.10.02 07:16
Оценка: 3 (1)
Здравствуйте AkaSaint, Вы писали:

AS>Здравствуйте Павел Кузнецов, Вы писали:


ПК>>Здравствуйте AkaSaint, Вы писали:


AS>>>Вопрос: как можно реализовать сабж на чистом С/С++ или в MSVC 7?


ПК>>В каком контексте? Решений есть несколько, каждое хорошо на своем месте.


AS>Контекст такой: есть класс — окно со скином, он предоставляет возможность тому, кто его использует, устанавливать свои обработчики сообщений, типа OnClose.


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


struct CSkinedWndEventsSink
{
  virtual void OnClose( ) = 0;
  virtual void OnChotToTam( ) = 0;
};


у твоего класса заводишь методы

class CSkinedWnd //это вроде как твой класс
{
  void Connect( CSkinedWndEventsSink *pSink );
  void Disconnect( CSkinedWndEventsSink *pSink );
}

что они должны делать понятно вроде

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

это упрощенный вариант обработки событий успользуемый в COM, так что можешь почитать для ознакомления с оригиналом

Ed.ward
Re[4]: Универсальный указатель на функцию-член класса
От: Anton V. Kolotaev  
Дата: 07.10.02 08:12
Оценка: 2 (1)
Здравствуйте Ed.ward, Вы писали:

EW>в этом случае гораздо удобнее воспользоваться интерфейсами, заводишь структуру типа этой


EW>ну а теперь любой кто хочет обрабатывать события от CSkinedWnd должен наследоваться от CSkinedWndEventsSink и реализовать его методы. А в рантайме где надо приконнектится, а где надо отконнектится


В том то и прелесть замыкания, что наследоваться ни от кого и не надо. Достаточно совпадения сигнатур. На практике разница будет заключаться в том, что с замыканием можно использовать классы, написанные до CSkinedWndEventsSink. Без замыканий — придется для существующих классов делать еще один подкласс, который реализует эти методы CSkinedWndEventsSink.

Решение без замыканий плохо масштабируется: при большом числе sink'ов возникнут трудности с тем, как устроить их иерархию, а именно следующая проблема дизайна: определить удачный интерфейс sink'a.

EW>это упрощенный вариант обработки событий успользуемый в COM, так что можешь почитать для ознакомления с оригиналом


В отсутствие замыканий, конечно, приходится пользоваться sink'ами.

PS. Кстати, кто-нибудь знает причину, что помешало ввести замыкания в C++?
Re[3]: Универсальный указатель на функцию-член класса
От: Павел Кузнецов  
Дата: 07.10.02 08:49
Оценка: 18 (3)
Здравствуйте AkaSaint, Вы писали:

AS>Контекст такой: есть класс — окно со скином, он предоставляет возможность тому, кто его использует, устанавливать свои обработчики сообщений, типа OnClose.


В рамках стандартного C++ наиболее адекватным решением являются всевозможные callback libraries: http://www.function-pointer.org/links.html#fpt
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Универсальный указатель на функцию-член класса
От: Vladik Россия  
Дата: 07.10.02 10:49
Оценка: 1 (1)
Здравствуйте AkaSaint, Вы писали:

AS>Контекст такой: есть класс — окно со скином, он предоставляет возможность тому, кто его использует, устанавливать свои обработчики сообщений, типа OnClose.


Забей на эту порочную дельфовскую технологию Используй интерфейсы. Благо а С++ есть множественное наследование. ИМХО чисто идеологически это намного правильнее, чем куча неизвестно куда торчащих "указателей-событий".
Как все запущенно...
Re[4]: Универсальный указатель на функцию-член класса
От: Anton V. Kolotaev  
Дата: 07.10.02 10:54
Оценка:
Здравствуйте Vladik, Вы писали:

V>Забей на эту порочную дельфовскую технологию Используй интерфейсы. Благо а С++ есть множественное наследование. ИМХО чисто идеологически это намного правильнее, чем куча неизвестно куда торчащих "указателей-событий".


Хотелось бы услышать осмысленную мотивацию
Re[5]: Универсальный указатель на функцию-член класса
От: Vladik Россия  
Дата: 07.10.02 11:09
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>Хотелось бы услышать осмысленную мотивацию


Вызывается неизвестно какая функция неизвестно какого класса. Почти как void *. Да, компилятор делает необходимые проверки для обеспечения корректности вызова (соглашение вызова, число и тип параметров). Но "идеологический" смысл теряется. В конце концов приходим к запутанным цепочкам таких недекларированных связей между классами.
Как все запущенно...
Re[6]: Универсальный указатель на функцию-член класса
От: Anton V. Kolotaev  
Дата: 07.10.02 11:35
Оценка:
Здравствуйте Vladik, Вы писали:

V>Здравствуйте Anton V. Kolotaev, Вы писали:


AVK>>Хотелось бы услышать осмысленную мотивацию


V>Вызывается неизвестно какая функция неизвестно какого класса.


Разве это так плохо?

V>Почти как void *.


Разве? Следующей фразой ты сказал, что нет

V>Да, компилятор делает необходимые проверки для обеспечения корректности вызова (соглашение вызова, число и тип параметров).


V>Но "идеологический" смысл теряется.


Что это такое?

V>В конце концов приходим к запутанным цепочкам таких недекларированных связей между классами.


Хм-м-м... Такие же "недекларированные" связи получаются и при использовании шаблонов: аргумент шаблона не обязан принадлежать некой иерархии классов. Более того, ограничения на сигнатуру его методов значительно более слабые — достаточно не совпадения сигнатур, а возможности вызова (что, вообще говоря, я интенсивно использую). Замыкания позволяют менять во время исполнения и тип объекта, и его вызываемый метод. Это несколько иная идиома. Я ей не пользовался, и мне интересно, чем она плоха и чему может помешать ее наличие в С++.
Re[7]: Универсальный указатель на функцию-член класса
От: Vladik Россия  
Дата: 07.10.02 11:54
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

V>>Вызывается неизвестно какая функция неизвестно какого класса.

AVK>Разве это так плохо?

Да.

[...]
V>>Да, компилятор делает необходимые проверки для обеспечения корректности вызова (соглашение вызова, число и тип параметров).
V>>Но "идеологический" смысл теряется.
AVK>Что это такое?

Это материал, как минимум, одной толстой книжки по ООП.

V>>В конце концов приходим к запутанным цепочкам таких недекларированных связей между классами.


AVK>Хм-м-м... Такие же "недекларированные" связи получаются и при использовании шаблонов:


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

AVK>аргумент шаблона не обязан принадлежать некой иерархии классов. Более того, ограничения на сигнатуру его методов значительно более слабые — достаточно не совпадения сигнатур, а возможности вызова (что, вообще говоря, я интенсивно использую). Замыкания позволяют менять во время исполнения и тип объекта, и его вызываемый метод. Это несколько иная идиома. Я ей не пользовался, и мне интересно, чем она плоха и чему может помешать ее наличие в С++.


Эта идиома не соответствует духу С++ с его строгой типизацией и изначальной статичностью типов.
Как все запущенно...
Re[5]: Универсальный указатель на функцию-член класса
От: AkaSaint  
Дата: 07.10.02 12:43
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>В том то и прелесть замыкания, что наследоваться ни от кого и не надо. Достаточно совпадения сигнатур. На практике разница будет заключаться в том, что с замыканием можно использовать классы, написанные до CSkinedWndEventsSink. Без замыканий — придется для существующих классов делать еще один подкласс, который реализует эти методы CSkinedWndEventsSink.


А можно дать, так сказать, формальное определение замыканий? Как я понял, один из примеров — обработчики событий в VCL. И спасибо за ответ
Re[6]: Универсальный указатель на функцию-член класса
От: Anton V. Kolotaev  
Дата: 07.10.02 12:51
Оценка:
Здравствуйте AkaSaint, Вы писали:

AS>А можно дать, так сказать, формальное определение замыканий? Как я понял, один из примеров — обработчики событий в VCL. И спасибо за ответ


К сожалению, как я уже сказал в соседнем топике, я ими не пользовался.
Re[7]: Универсальный указатель на функцию-член класса
От: Gadsky Россия  
Дата: 08.10.02 05:25
Оценка:
Используя closure будет использован только
_один_ обработчик. А если вдруг захочется много?
Тогда опять же придется извращаться с созданием
класса диспетчера...

Мне кажется использование подключаемых-отключаемых
обработчиков событий — более эффективная вещь.
В Java Swing они активно используются — мне очень понравилось.
А на C++ из-за множественного наследования эта технология
еще легче реализуется...
Re[8]: Универсальный указатель на функцию-член класса
От: Аноним  
Дата: 08.10.02 13:33
Оценка:
Здравствуйте Vladik, Вы писали:

AVK>>Хм-м-м... Такие же "недекларированные" связи получаются и при использовании шаблонов:


V>Не совсем. Шаблоны все же декларируются на этапе компиляции. __closure, как ты сам заметил, — нет.


Чего?

AVK>>аргумент шаблона не обязан принадлежать некой иерархии классов. Более того, ограничения на сигнатуру его методов значительно более слабые — достаточно не совпадения сигнатур, а возможности вызова (что, вообще говоря, я интенсивно использую). Замыкания позволяют менять во время исполнения и тип объекта, и его вызываемый метод. Это несколько иная идиома. Я ей не пользовался, и мне интересно, чем она плоха и чему может помешать ее наличие в С++.


V>Эта идиома не соответствует духу С++ с его строгой типизацией и изначальной статичностью типов.


Чего-чего? Ты вообще о чем? Ты вообще знаешь синтаксис __closure? Причем здесь вообще строгая типизация?
Re[9]: Универсальный указатель на функцию-член класса
От: Vladik Россия  
Дата: 08.10.02 13:47
Оценка:
Здравствуйте Аноним, Вы писали:

V>>Не совсем. Шаблоны все же декларируются на этапе компиляции. __closure, как ты сам заметил, — нет.

А>Чего?

А ты кто? Чего непонятно-то?

[...]
V>>Эта идиома не соответствует духу С++ с его строгой типизацией и изначальной статичностью типов.
А>Чего-чего? Ты вообще о чем? Ты вообще знаешь синтаксис __closure?

Знаю.

А>Причем здесь вообще строгая типизация?


При том, что она есть в С++. Я попытался как-то аргументировать свою позицию, если тебе что-то непонятно или ты с чем-то не согласен — выражайся конкретнее.
Как все запущенно...
Re[8]: Универсальный указатель на функцию-член класса
От: Павел Кузнецов  
Дата: 08.10.02 15:01
Оценка: 5 (1)
Здравствуйте Vladik, Вы писали:

AVK>>аргумент шаблона не обязан принадлежать некой иерархии классов. Более того, ограничения на сигнатуру его методов значительно более слабые — достаточно не совпадения сигнатур, а возможности вызова (что, вообще говоря, я интенсивно использую). Замыкания позволяют менять во время исполнения и тип объекта, и его вызываемый метод. Это несколько иная идиома. Я ей не пользовался, и мне интересно, чем она плоха и чему может помешать ее наличие в С++.


V>Эта идиома не соответствует духу С++ с его строгой типизацией и изначальной статичностью типов.


Отнюдь. Семантически __closure являются разновидностью лямбда-функций со связанными аргументами, которые, в свою очередь, достаточно близки функционалам, являющимся частью стандартной библиотеки, а также предоставляемыми многочисленными сторонними библиотеками. __closure могут быть симулированы для конечного количества аргументов соответствующей библиотекой, например libsigc++. Наличие поддержки со стороны компилятора ничего "идеологически" не поменяет и строгую типизацию не нарушит.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[9]: Универсальный указатель на функцию-член класса
От: Vladik Россия  
Дата: 08.10.02 19:53
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

V>>Эта идиома не соответствует духу С++ с его строгой типизацией и изначальной статичностью типов.

ПК>Отнюдь. Семантически __closure являются разновидностью лямбда-функций со связанными аргументами,

А я думал лямбда-функции только в лиспе есть...

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


Как ты лихо от одного к совершенно другому пришел

ПК>__closure могут быть симулированы для конечного количества аргументов соответствующей библиотекой, например libsigc++. Наличие поддержки со стороны компилятора ничего "идеологически" не поменяет и строгую типизацию не нарушит.


Может я чего не понимаю, тогда поправьте меня. Вот простейший "аналог" __closure на классическом С++ (как я его себе представляю):

// аналог __closure для функции с одним аргументом
template <typename T, typename R, typename A1>
class closure1_t
{
    T &m_this;
    R (T::*m_f)(A1);
public:
    closure1_t(T &t, R (T::*f)(A1)):m_this(t), m_f(f){}
    R operator () (A1 a1){ return (m_this.*m_f)(a1);}
};    
...
closure1_t<X, int, char> closure1(x, &X::f);
    closure1('a'); // вот чего мы хотели


Принципиальной вещью, добавляющей ту самую "статичность" типов является наличие в объявлении в качестве параметра шаблона X — класса, на функцию которого мы завязываемся. В случае __closure в C++Builder — класс X неизвестен. Что для С++ будет "грязным хаком" (выделено жирным):

template <typename R, typename A1>
class unk_closure1_t
{
    class T{};

    T &m_this;
    R (T::*m_f)(A1);
public:
    template <typename UnkT>
    unk_closure1_t(UnkT &t, R (UnkT::*f)(A1))
            :m_this(reinterpret_cast<T &>(t)), 
             m_f(reinterpret_cast<R (T::*)(A1)>(f)){}
    R operator () (A1 a1){ return (m_this.*m_f)(a1);}
};    
...
unk_closure1_t<int, char> __closure1(x, &X::f);
    __closure1('a');  // типа должно работать ;)
Как все запущенно...
Re[10]: Универсальный указатель на функцию-член класса
От: Павел Кузнецов  
Дата: 09.10.02 07:14
Оценка: 2 (1)
Здравствуйте Vladik, Вы писали:

V>А я думал лямбда-функции только в лиспе есть... ;)


Не только. На уровне языка C++, конечно, их не поддерживает, но соответствующие библиотеки имеются.

ПК>>__closure могут быть симулированы для конечного количества аргументов соответствующей библиотекой, например libsigc++. Наличие поддержки со стороны компилятора ничего "идеологически" не поменяет и строгую типизацию не нарушит.


V>Может я чего не понимаю, тогда поправьте меня. Вот простейший "аналог" __closure на классическом С++ (как я его себе представляю):


V>
V>// аналог __closure для функции с одним аргументом
V>template <typename T, typename R, typename A1>
V>class closure1_t
V>{
V>    T &m_this;
V>    R (T::*m_f)(A1);
V>public:
V>    closure1_t(T &t, R (T::*f)(A1)):m_this(t), m_f(f){}
V>    R operator () (A1 a1){ return (m_this.*m_f)(a1);}
V>};    
V>...
V>closure1_t<X, int, char> closure1(x, &X::f);
V>    closure1('a'); // вот чего мы хотели
V>


V>Принципиальной вещью, добавляющей ту самую "статичность" типов является наличие в объявлении в качестве параметра шаблона X — класса, на функцию которого мы завязываемся. В случае __closure в C++Builder — класс X неизвестен. Что для С++ будет "грязным хаком" (выделено жирным):


Приведенный пример можно переписать иначе, скрыв информацию о классе Х от того, кто будет вызывать closure (схематичный код, не претендующий на правильность и/или полноту):

struct AbstractSignal
{
  virtual ~AbstractSignal() { }
};

template<class R, class A1>
struct AbstractSignal1
{
  virtual R operator()(A1) const = 0;
};

// RTTI-обертка для AbstractSignal1, предназначена для использования конечным пользователем
template<class R, class A1>
class Signal1
{
public:
  Signal1(AbstractSignal1<R, A1>* signal = 0) : m_signal (signal) { }

  R operator()(A1 a1) const { return (*m_signal)(a1); }

private:
  // *** здесь должен быть какой-нибудь smart-pointer с подсчетом ссылок ***
  AbstractSignal1<R, A1>* m_signal;
};

template<class R, class T, class A1>
class MemFun1Closure1 : public AbstractSignal1<R, A1>
{
public:
  MemFun1Closure1(R (T::*f)(A1), T& t) : m_f (f), m_this (t) { }

  R operator()(A1 a1) const { return (m_this.*m_f)(a1); }

private:
  R (T::*m_f)(A1);
  T& m_this;
};

template<class R, class A1, class T>
Signal1<R, A1> closure(R (T::*f)(A1), T& t)
{
  return Signal1<R, A1>(new MemFun1Closure1<R, T, A1>(f, t));
}


Таким образом, пользователь не будет знать о классе T ни в момент вызова, ни в месте объявления signal:

class X
{
public:
  int foo(double);
};

int main()
{
  // В этой точке информация о классе X не нужна: Signal1 может быть проинициализирован и обычной функцией, если реализовать соответствующий PtrFunXClosure1.
  Signal1<int, double> signal;

  // . . .

  // Это единственное место, где пользователь упоминает класс X.
  X x;
  signal = closure(&X::foo, x);

  // . . .

  // В этой точке информация о существовании класса X пользователю тоже не нужна.
  return signal(0.5);
}


Поддержка со стороны компилятора потенциально позволяет избавиться от динамического распределения памяти (или спрятать его), но ничего не меняет принципиально.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[10]: Универсальный указатель на функцию-член класса
От: Андрей Тарасевич Беларусь  
Дата: 09.10.02 07:23
Оценка: 5 (1)
Здравствуйте Vladik, Вы писали:

V>Может я чего не понимаю, тогда поправьте меня. Вот простейший "аналог" __closure на классическом С++ (как я его себе представляю):


Все это интересно и полезно, но тем не менее ни одно решение на классическом С++ не позволяет, к сожалению, закрыть, наконец, пропасть между функциональными объектами и функциями, т.е. написать реентерабельный closure, результатом котрого была бы обычная функция (указатель на функцию), а не функциональный объект. Платформенно-зависимые решения, разумеется, присутствуют. Портабельных решений нет.
Best regards,
Андрей Тарасевич
Re[11]: Универсальный указатель на функцию-член класса
От: Vladik Россия  
Дата: 09.10.02 07:27
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

V>>Принципиальной вещью, добавляющей ту самую "статичность" типов является наличие в объявлении в качестве параметра шаблона X — класса, на функцию которого мы завязываемся. В случае __closure в C++Builder — класс X неизвестен. Что для С++ будет "грязным хаком" (выделено жирным):


ПК>Приведенный пример можно переписать иначе, скрыв информацию о классе Х от того, кто будет вызывать closure (схематичный код, не претендующий на правильность и/или полноту):


Да уж. Без поллитры такое не придумать. От reinterpret_cast ушли, но какой ценой

[...]

ПК>Поддержка со стороны компилятора потенциально позволяет избавиться от динамического распределения памяти (или спрятать его), но ничего не меняет принципиально.


Да я ничего не имею против поддержки со стороны компилятора, я даже за. Я говорю о том, что легкость подобного подхода будет провоцировать использовать его там, где не надо (что я вижу в билдере).
Как все запущенно...
Re[12]: Универсальный указатель на функцию-член класса
От: Павел Кузнецов  
Дата: 09.10.02 08:00
Оценка:
Здравствуйте Vladik, Вы писали:

ПК>>Поддержка со стороны компилятора потенциально позволяет избавиться от динамического распределения памяти (или спрятать его), но ничего не меняет принципиально.


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


Ну, это уже совсем другой разговор. Воспитание манер не является задачей языка.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Универсальный указатель на функцию-член класса
От: Аноним  
Дата: 20.10.02 15:07
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>В рамках стандартного C++ наиболее адекватным решением являются всевозможные callback libraries: http://www.function-pointer.org/links.html#fpt


А кто нибудь проверял эту либу
http://www.function-pointer.org/zip/callback.zip ? Потому как у меня при использовании класса с множественным наследованием это все дружно рухнуло, и заглянув в класс CBFunctorBase на вскидку изменил вот так вот —

enum {MEM_FUNC_SIZE = sizeof(PMemFunc)*2};

На первый взгляд должно работать, но неизвестно к каким еще багам это может привести? Вообще есть какая то более легальная имплементация, что бы учитывалась 8-ми байтная структура указателя на метод класса, полученного множественным наследованием, как то обойтись без memcpy&memcmp, ну и что бы оператор == присутсвовал как в данной реализации?
Re: Универсальный указатель на функцию-член класса
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 21.10.02 08:51
Оценка: +1
Здравствуйте AkaSaint, Вы писали:

AS>Вопрос: как можно реализовать сабж на чистом С/С++ или в MSVC 7? В Билдере есть очень удобная штука — __closure, с ее помощью можно определить указатель на функцию — член любого класса, лишь бы параметры и возвращаемые значения совпадали (ну и соглашения по вызову). А в MSVC получается, мне еще нужно знать, и какого класса функция.... Помогите пожалуйста.


Вопрос появляется с завидным постоянством

Насколько я понял принцип работы __closure

В указателе на метод хранятся
  1. указатель на объект (void*)
  2. указатель на функцию, которая вызывает конкретный метод, конкретного класса
То есть когда ты выполняешь присваивание
closure_variable=object.method

компилятор создает заглушку, которая именно этот метод и вызывает:
result_type method_caller(object_type* object,arg_list)
{
 return object->method(arg_list)
}


И сохраняет в closure_variabe {(void*)this,method_caller}.

Значит нам нужно соорудить шаблонные конструкции, которые будут порождать
  1. Класс для хранения данных __closure
  2. Класс, в котором будет статический метод вызова указанного метода — *object_type::mem_func(arg_list). Указатель на обслуживаемый метод естественно должен храниться в статическом члене этого класса
  3. Шаблонная функция, которая автоматизирует процесс создания содержимого __closure. Например, такого вида
    template<class object_type,/*перечисляем типы из arg_list*/>
    closure_variable_type make_closure(object_type* obj,void (object_type::*method)(arg_list))
Естественно, то что Builder делает на уровне компилятора, прийдется собирать руками под разное число аргументов и разные типы вызово (__stdcall,__cdecl)

Это и есть вся теория __closure.

На практике, когда я пробовал это соорудить на BCB3, получилось следующее
Автор: Коваленко Дмитрий
Дата: 28.01.02


Надеюсь, что ответил по существу.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: Универсальный указатель на функцию-член класса
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 21.10.02 09:06
Оценка:
Здравствуйте Коваленко Дмитрий, Вы писали:

Хм. немножно неправильно объяснил

КД>компилятор создает заглушку, которая именно этот метод и вызывает:

КД>
КД>result_type method_caller(void* object,arg_list)
КД>{
КД> return ((object_type*)object)->method(arg_list);
КД>}
КД>


Заглушка должна быть такого вида. Под каждый класс object_type и каждый method нужно генерировать свою заглушку.

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

Теперь, кажется, все перепутано правильно
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.