Re[6]: EventHandler
От: MaximE Великобритания  
Дата: 07.08.03 14:06
Оценка: :))
Здравствуйте, Павел Кузнецов, Вы писали:

M>>

Herb Sutter
M>> The function facility, recently adopted by the C++ standards committee


ПК>Здесь Саттер не вполне точен: в настоящий момент некоторая часть "фич" внесена голосованием

ПК>членов комитета в Technical Report 1, который стандартом не является. В частности, эти "фичи"
ПК>в очередной стандарт могут и не войти: нормативным документом TR не является.

А если не войдут, придется смахнуть пыль со старого доброго BFG9000 и навестить заседание комитета
Re: EventHandler
От: ioni Россия  
Дата: 06.08.03 07:02
Оценка: 6 (1)
Здравствуйте, Снорк, Вы писали:

С>Можно ли в C++ передать в шаблон не только имя типа, но и имя метода?


а почему бы нет

#if !defined __ICOMMAND_H__
#define __ICOMMAND_H__

#include "../../System/Loki/Functor.h"

//////////////////////////////////////////////////////////////////////////
class ICommand
{
public:
    virtual ~ICommand() {}
    void execute() { do_execute(); }
protected:
    virtual void do_execute() = 0;
};
//////////////////////////////////////////////////////////////////////////
template<typename TClass>
class CommandHelperFuncPtr : public ICommand
{
public:
    CommandHelperFuncPtr(TClass &t, void (TClass::*pFunc)()) : t_(t), pFunc_(pFunc) {}
protected:
    virtual void do_execute()
    { (t_.*pFunc_)(); }
private:
    TClass t_;
    void (TClass::*pFunc_)();
};
//////////////////////////////////////////////////////////////////////////
// void TClass::foo();
// TClass parent_;
//    CommandHelper<TClass> e(parent_, TClass::foo);
//    e.execute();

//////////////////////////////////////////////////////////////////////////
template<typename TFunctor>
class CommandHelperPtr : public ICommand
{
public:
    CommandHelperPtr(TFunctor *pf) : tfunc_(pf) {}
    ~CommandHelperPtr() { delete tfunc_; }
protected:
    virtual void do_execute()
    { (*tfunc_)(); }
private:
    TFunctor *tfunc_;
};
//////////////////////////////////////////////////////////////////////////
template <typename TFunctor>
class CommandHelperRef: public ICommand
{
public:
    CommandHelperRef(TFunctor &pf) : tfunc_(pf) {}
protected:
    virtual void do_execute() { tfunc_(); }
private:
    TFunctor &tfunc_;
};
//////////////////////////////////////////////////////////////////////////
// Parent pnt;
// typedef Functor<void> my_func;
// my_func classFunctor(&pnt, &Parent::call_me);
// CommandFunctor<my_func> e(classFunctor);
// e.execute();
//////////////////////////////////////////////////////////////////////////
Re: EventHandler
От: kly Россия  
Дата: 06.08.03 07:06
Оценка: 6 (1)
Здравствуйте, Снорк, Вы писали:

С>Можно ли в C++ передать в шаблон не только имя типа, но и имя метода?


С>Вот исходник, который по понятным причинам не работает:


С>
С>template<class T, class M> class CRN
С>{
С>public:
С>    CRN(T* pObject)
С>    {
С>        m_pObject = pObject;
С>    }

С>    void Notify()
С>    {
С>        m_pObject->M();
С>    }

С>protected:

С>    T*        m_pObject;
С>};
С>


С>Планировалось его использовать следующим образом:


С>
С>class C {
С>...
С>void SetEventHandler(CRN* pHandler);
С>...
С>void OnEvent()
С>{
С>    pHandler->Notify();
С>}
С>};

С>void Lalamba(C* p, Object* pObject)
С>{
    p->>SetEventHandler(new CRN<Object, Method>(pObject))
С>}
С>


С>Что приводило бы к вызову метода Method у экземпляра, указуемого p.


С>Как можно решить эту проблему в общем случае?



Воспользуйся указателями на метод

template< class T >
class CRN2
{
  CRN2( T* src, ClassMethod ahandler ) : ptr( src ), handler( ahandler ) {};

  void Notify( void )
  {
      (ptr->*handler)();
  }

private:
   typedef void (T::*ClassMethod)(void);
   T* ptr;
   ClassMethod handler;
};

void main( void )
{
   CRN2< SomeClass > a( &SomeClassVar, &SomeClass::Method );

   a.Notity();
}


для общего решения читай
здесь
Автор(ы): Александр Шаргин
Дата: 19.03.2003
Делегаты в CLR удобны, типобезопасны и эффективны. Последнее время на форумах RSDN часто поднимается вопрос о том, можно ли реализовать делегаты с аналогичными свойствами, оставаясь в рамках "чистого" C++. Оказывается, это вполне возможно. В этой статье я покажу, как это сделать.
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, — недооценка изобретательности клинических идиотов.

http://www.inconteam.com
Re: EventHandler
От: addword Украина  
Дата: 06.08.03 07:45
Оценка: 6 (1)
Здравствуйте, Снорк, Вы писали:

С>Можно ли в C++ передать в шаблон не только имя типа, но и имя метода?


С>Вот исходник, который по понятным причинам не работает:


С>
С>template<class T, class M> class CRN
С>{
С>public:
С>    CRN(T* pObject)
С>    {
С>        m_pObject = pObject;
С>    }

С>    void Notify()
С>    {
С>        m_pObject->M();
С>    }

С>protected:

С>    T*        m_pObject;
С>};
С>


С>Планировалось его использовать следующим образом:


С>
С>class C {
С>...
С>void SetEventHandler(CRN* pHandler);
С>...
С>void OnEvent()
С>{
С>    pHandler->Notify();
С>}
С>};

С>void Lalamba(C* p, Object* pObject)
С>{
    p->>SetEventHandler(new CRN<Object, Method>(pObject))
С>}
С>


С>Что приводило бы к вызову метода Method у экземпляра, указуемого p.


С>Как можно решить эту проблему в общем случае?


В данном случае необходимо реализовать так называемые замыкания (closure), типа как в Builder или Delphi.
Задавать в качестве параметра шаблона имя метода нельзя. Вообще параметром шаблона может быть только константное выражение — имя типа, константа простого типа.
Необходимо использовать указатель на метод класса.
Эту задачу можно решить при помощи обобщённого функтора из шаблонной библиотеки Александреску "Loki". Его функторы позволяют реализовать замыкания (по крайней мере он так пишет в своей книге).
EventHandler
От: Снорк  
Дата: 06.08.03 06:51
Оценка:
Можно ли в C++ передать в шаблон не только имя типа, но и имя метода?

Вот исходник, который по понятным причинам не работает:

template<class T, class M> class CRN
{
public:
    CRN(T* pObject)
    {
        m_pObject = pObject;
    }

    void Notify()
    {
        m_pObject->M();
    }

protected:

    T*        m_pObject;
};


Планировалось его использовать следующим образом:

class C {
...
void SetEventHandler(CRN* pHandler);
...
void OnEvent()
{
    pHandler->Notify();
}
};

void Lalamba(C* p, Object* pObject)
{
    p->SetEventHandler(new CRN<Object, Method>(pObject))
}


Что приводило бы к вызову метода Method у экземпляра, указуемого p.

Как можно решить эту проблему в общем случае?
Re[2]: EventHandler
От: Аноним  
Дата: 06.08.03 07:50
Оценка:
Здравствуйте, addword, Вы писали:

A>В данном случае необходимо реализовать так называемые замыкания (closure), типа как в Builder или Delphi.

A>Задавать в качестве параметра шаблона имя метода нельзя. Вообще параметром шаблона может быть только константное выражение — имя типа, константа простого типа.

Но ведь к простым типам относятся и указатели на члены.
Re: EventHandler
От: Павел Кузнецов  
Дата: 06.08.03 15:01
Оценка:
Здравствуйте, Снорк, Вы писали:

С> Можно ли в C++ передать в шаблон не только имя типа, но и имя метода?


Можно, только не имя, а указатель на член.

С>
С> template<class T, class M> class CRN
С> {
С> public:
С>  CRN(T* pObject)
С>  {
С>   m_pObject = pObject;
С>  }

С>  void Notify()
С>  {
С>   m_pObject->M();
С>  }

С> protected:

С>  T*  m_pObject;
С> };
С>


template<class T, void (T::*M)()> class CRN
{
public:
    CRN(T* pObject)
    {
        m_pObject = pObject;
    }

    void Notify()
    {
        (m_pObject->*M)();
    }

protected:
    T*        m_pObject;
};


С> Планировалось его использовать следующим образом:


С>
С> class C {
С> ...
С> void SetEventHandler(CRN* pHandler);
С> ...
С> void OnEvent()
С> {
С>     pHandler->Notify();
С> }
С> };

С> void Lalamba(C* p, Object* pObject)
С> {
С>     p->SetEventHandler(new CRN<Object, Method>(pObject))
С> }
С>


С> Что приводило бы к вызову метода Method у экземпляра, указуемого p.


class C {
...
void SetEventHandler(CRN* pHandler);
...
void OnEvent()
{
    pHandler->Notify();
}
};

void Lalamba(C* p, Object* pObject)
{
    p->SetEventHandler(new CRN<Object, &Object::Method>(pObject))
}


P.S. В VC++6.0 в буквальном виде работать не будет, но при желании можно "подправить".
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: EventHandler
От: WolfHound  
Дата: 06.08.03 15:17
Оценка:
Здравствуйте, Снорк, Вы писали:

2all: Ну зачем такие сложности?


template<class T, void(T::*M)()> 
class CRN
{
public:
    CRN(T* pObject)
    {
        m_pObject = pObject;
    }

    void Notify()
    {
        (m_pObject->*M)();
    }

protected:

    T*        m_pObject;
};
 
class G
{
public:
    void gg()
    {
        std::cout<<"hello\n";
    }
};

int main()
{
    G g;
    CRN<G, &G::gg> asd(&g);
    asd.Notify();
    return 0;
}
... << RSDN@Home 1.1 alpha 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: EventHandler
От: MaximE Великобритания  
Дата: 07.08.03 07:35
Оценка:
Здравствуйте, addword, Вы писали:

A>В данном случае необходимо реализовать так называемые замыкания (closure), типа как в Builder или Delphi.


Давно уже все реализовано и включено в слудующий стандарт stl — boost::function<>.
Re[3]: EventHandler
От: addword Украина  
Дата: 07.08.03 11:28
Оценка:
Здравствуйте, MaximE, Вы писали:

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


A>>В данном случае необходимо реализовать так называемые замыкания (closure), типа как в Builder или Delphi.


ME>Давно уже все реализовано и включено в слудующий стандарт stl — boost::function<>.


Я же не сказал что это не сделано. Я же привёл в пример библиотеку Loki. Естественно в ей подобных тоже это есть (и про boost я знаю). Я же не могу перечислять все библиотеки Но у меня к Вам вопрос — когда это библиотека boost стала стандартом?
Re[4]: EventHandler
От: MaximE Великобритания  
Дата: 07.08.03 12:31
Оценка:
Здравствуйте, addword, Вы писали:

ME>>Давно уже все реализовано и включено в слудующий стандарт stl — boost::function<>.


A>Я же не сказал что это не сделано. Я же привёл в пример библиотеку Loki. Естественно в ей подобных тоже это есть (и про boost я знаю). Я же не могу перечислять все библиотеки Но у меня к Вам вопрос — когда это библиотека boost стала стандартом?


The New C++

Generalized Function Pointers

Herb Sutter
The function facility, recently adopted by the C++ standards committee, provides a generalized way of working with arbitrary functions when all you know (or need to know) is their signature. In fact, as it turns out, you don't even need to know the target function's exact signature -- any target function with a compatible signature, meaning one where the parameter and return types are appropriately covertible, will work just fine.

Re[5]: EventHandler
От: Павел Кузнецов  
Дата: 07.08.03 14:02
Оценка:
Здравствуйте, MaximE, Вы писали:

A>> Но у меня к Вам вопрос — когда это библиотека boost стала стандартом?


M>

Herb Sutter
M> The function facility, recently adopted by the C++ standards committee


Здесь Саттер не вполне точен: в настоящий момент некоторая часть "фич" внесена голосованием
членов комитета в Technical Report 1, который стандартом не является. В частности, эти "фичи"
в очередной стандарт могут и не войти: нормативным документом TR не является.
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: EventHandler
От: addword Украина  
Дата: 07.08.03 14:36
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


A>>> Но у меня к Вам вопрос — когда это библиотека boost стала стандартом?


M>>

Herb Sutter
M>> The function facility, recently adopted by the C++ standards committee


ПК>Здесь Саттер не вполне точен: в настоящий момент некоторая часть "фич" внесена голосованием

ПК>членов комитета в Technical Report 1, который стандартом не является. В частности, эти "фичи"
ПК>в очередной стандарт могут и не войти: нормативным документом TR не является.

Об этом я и говорю.
Re[2]: EventHandler
От: phwp  
Дата: 07.08.03 17:56
Оценка:
Здравствуйте, WolfHound, Вы писали:

С передачей указателя на функцию в качестве параметра темплейта проблем нет:
template < class T, short ( fn ) ( T * ) >
short some_func ( T * i_val )
{ return fn ( i_val ); }

Я столкнулся с проблемой, что в примере выше нельзя передать даже
инстанциированный шаблон функции в качестве параметра шаблона.
template < class T > inline
short func ( T * i_val )
{ return 0; }

Это в VC6. В gcc такой подход нормально работает.


WH>Здравствуйте, Снорк, Вы писали:


WH>2all: Ну зачем такие сложности?



WH>
WH>template<class T, void(T::*M)()> 
WH>class CRN
WH>{
WH>public:
WH>    CRN(T* pObject)
WH>    {
WH>        m_pObject = pObject;
WH>    }

WH>    void Notify()
WH>    {
WH>        (m_pObject->*M)();
WH>    }

WH>protected:

WH>    T*        m_pObject;
WH>};
 
WH>class G
WH>{
WH>public:
WH>    void gg()
WH>    {
WH>        std::cout<<"hello\n";
WH>    }
WH>};

WH>int main()
WH>{
WH>    G g;
WH>    CRN<G, &G::gg> asd(&g);
WH>    asd.Notify();
WH>    return 0;
WH>}
WH>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.