简体   繁体   English

C ++反复出现的模板模式,语法错误

[英]C++ Curiously recurring template pattern, syntax error

I'm trying to write a template event class and keep as much code as possible inside this base class. 我试图编写一个模板事件类,并在此基类中保留尽可能多的代码。 I'm using the curiously recurring template pattern, but i'm not exactly sure about what i'm doing here. 我正在使用反复出现的模板模式,但是我不确定我在这里做什么。

template< class EventType >
class Event
{
protected:

    std::vector< EventType::Listener * > m_aListeners;

public:

    void operator += ( EventType::Listener * pListener )
    {
        m_aListeners.push_back( pListener );
    }

    void operator -= ( EventType::Listener * pListener )
    {
        std::vector< EventType::Listener * >::reverse_iterator revIter = m_aListeners.rbegin();
        for( ; revIter != m_aListeners.rend(); ++revIter )
            if( revIter == pListener )
            {
                m_aListeners.remove( revIter );
                break;
            }
    }

    void Trigger( EventType::Data * pData )
    {
        std::vector< EventType::Listener * >::iterator iter = m_aListeners.begin();
        for( ; iter != m_aListeners.end(); ++iter )
            CallListenert( iter, pData );
    }

    virtual void CallListener( EventType::Listener * pListener, EventType::Data * pData ) = 0;
};

And its subclass for a given event type : 以及给定事件类型的子类:

class ConnectionSuccessEvent : public Event< ConnectionSuccessEvent >
{
public:

    class Data
    {
    public:
        Data( int iVal ) : m_iVal( iVal ) { }
    public:
        const int m_iVal;
    };

    class Listener
    {
    public:
        virtual ~Listener() { }
        virtual void OnConnectionSuccess( Data * pEventData ) = 0;
    };

    void CallListener( Listener * pListener, Data * pData )
    {
        pListener->OnConnectionSuccess( pData );
    }
};

And a class implementing the listener class : 还有一个实现监听器类的类:

class MyClass :  public ConnectionSuccessEvent::Listener
{
public:

    void OnConnectionSuccess( ConnectionSuccessEvent::Data * pEventData )
    {
        std::cout << "OnConnectionSuccess : " << pEventData->m_iVal << std::endl;
    }
};

Which i use as follows : 我使用如下:

MyClass oMyClassInstance;

ConnectionSuccessEvent oOnConnectionSuccess;

oOnConnectionSuccess += & oMyClassInstance;
oOnConnectionSuccess += & oMyClassInstance;

ConnectionSuccessEvent::Data oData( 456 );
oOnConnectionSuccess.Trigger( & oData );

oOnConnectionSuccess -= & oMyClassInstance;
oOnConnectionSuccess -= & oMyClassInstance;

This is resulting in several compilations errors, the first one being : 这导致了几个编译错误,第一个是:

Error 2 error C2059: syntax error : '>' c:\\dev\\eventtest\\event.h 16 错误2错误C2059:语法错误:'>'c:\\ dev \\ eventtest \\ event.h 16

Which corresponds to the declaration of the vector m_aListeners. 对应于向量m_aListeners的声明。

I have two questions : 我有两个问题:

  • What is causing my error ? 是什么导致我的错误? Am I not allowed to use EventType::Listener in my class Event ? 我不能在类Event中使用EventType :: Listener吗?

  • How is the curiously recurring pattern possible ? 奇怪的重复模式怎么可能? I mean, to be defined, the derived class requires its parent class be defined. 我的意思是,要定义,派生类需要定义其父类。 But since it's parent it's parent class requires it's template parameter class to be defined ie it's base class), then it's a problem, because for one to be defined, it needs the other one to be defined first. 但是因为它是父类,所以它的父类需要定义其模板参数类(即它的基类),所以这是一个问题,因为要定义一个,首先需要定义另一个。 This is like having an instance of A in class B, and an instance ob B in class A. 这就像在类B中有一个实例A,在类A中有一个实例obB。

Thank you ! 谢谢 !

EDIT : I can't use C++11. 编辑:我不能使用C ++ 11。

I found an acceptably ugly way to do that ! 我找到了一个可以接受的丑陋方法!

Base event class containing the behaviour of the event objects. 包含事件对象行为的基本事件类。

template< class EventListenerType, class EventDataType >
class BaseEvent
{
private:

    std::vector< EventListenerType * > m_aListeners;

public:

    void operator += ( EventListenerType * pListener )
    {
        m_aListeners.push_back( pListener );
    }

    void operator -= ( EventListenerType * pListener )
    {
        // When nI is 0 and gets decremented (i.e would be < 0), it "underflows" and
        // becomes >= m_aListeners.size(), so we can detect that the last element (i.e 
        // the first in position ) has been treated when nI >= m_aListeners.size().

        for( size_t nI = m_aListeners.size() - 1; nI <= m_aListeners.size(); --nI )
        {
            if( m_aListeners[ nI ] == pListener )
            {
                m_aListeners.erase( m_aListeners.begin() + nI );
                break;
            }
        }
    }

    void Trigger( EventDataType * pData )
    {
        for( size_t nI = 0; nI < m_aListeners.size(); ++nI )
            m_aListeners[ nI ]->OnEvent( pData );
    }
};

And : 和:

template< class EventDataType >
class EventListener
{
public:

    virtual ~EventListener() { }

    virtual void OnEvent( const EventDataType * pData ) = 0;
};

ConnectionSuccessEvent specific stuff : ConnectionSuccessEvent特定的东西:

class ConnectionSuccessEventData
{
public:
    const int m_iVal;
    ConnectionSuccessEventData( int iVal ) : m_iVal( iVal ) { }
};

typedef EventListener< ConnectionSuccessEventData > ConnectionSuccessEventListener;
typedef BaseEvent< ConnectionSuccessEventListener, ConnectionSuccessEventData > ConnectionSuccessEvent;

DataReceivedEvent specific stuff : DataReceivedEvent特定内容:

class DataReceivedEventData
{
public:
    const float m_fVal;
    DataReceivedEventData( float fVal ) : m_fVal( fVal ) { }
};

typedef EventListener< DataReceivedEventData > DataReceivedEventListener;
typedef BaseEvent< DataReceivedEventListener, DataReceivedEventData > DataReceivedEvent;

Listener class : 侦听器类:

class MyClass : public ConnectionSuccessEventListener, public DataReceivedEventListener
{
public:

    void OnEvent( const ConnectionSuccessEventData * pData )
    {
        std::cout << "Connection success event : " << pData->m_iVal << std::endl;
    }

    void OnEvent( const DataReceivedEventData * pData )
    {
        std::cout << "Data received event : " << pData->m_fVal << std::endl;
    }
};

Usage : 用法:

MyClass oMyClassInstance;

ConnectionSuccessEvent oOnConnectionSuccess;
DataReceivedEvent oOnDataReceived;

oOnConnectionSuccess += & oMyClassInstance;
oOnDataReceived += & oMyClassInstance;
oOnConnectionSuccess += & oMyClassInstance;
oOnDataReceived += & oMyClassInstance;

ConnectionSuccessEventData oConnectionSuccessData( 123 );
oOnConnectionSuccess.Trigger( & oConnectionSuccessData );

DataReceivedEventData oDataReceivedData( 0.0f );
oOnDataReceived.Trigger( & oDataReceivedData );

oOnDataReceived += & oMyClassInstance;
oOnConnectionSuccess -= & oMyClassInstance;
oOnDataReceived += & oMyClassInstance;
oOnConnectionSuccess -= & oMyClassInstance;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 奇怪的重复模板模式(CRTP),AutoLists和C ++ - Curiously Recurring Template Pattern (CRTP), AutoLists and C++ 如何在C ++中强制使用奇怪的重复模板模式 - How to force use of curiously recurring template pattern in C++ 奇怪的重复模板模式多态拷贝(C ++)中的继承 - Inheritance in curiously recurring template pattern polymorphic copy (C++) C ++ BigIntegers和奇怪的重复模板模式问题 - C++ BigIntegers and the Curiously Recurring Template Pattern Issue 具有可变参数模板的好奇重复模板模式(C ++) - Curiously recurring template pattern with variadic templates (C++) 我可以在这里使用 Curiously Recurring Template Pattern (C++) 吗? - Can I use the Curiously Recurring Template Pattern here (C++)? C++ 奇怪地重复出现的模板模式“使用未定义的结构”编译错误 - C++ Curiously Recurring Template Pattern “uses undefined struct” compile error C ++:奇怪的重复模板模式是什么?并且可以奇怪地重复模板模式取代虚拟功能? - C++: what is the Curiously-Recurring-Template-Pattern? and can Curiously-Recurring-Template-Pattern replace virtual functions? 将关键字与奇怪重复的模板模式一起使用时出错 - Error with using keyword with curiously recurring template pattern 具有ptrhead的奇怪重复模板模式 - Curiously recurring template pattern with ptrhead
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM