C ++好奇地反复出现模板模式,语法错误

C++ Curiously recurring template pattern, syntax error

我正在尝试编写一个模板事件类,并在这个基类中尽可能多地保留代码。我正在使用奇怪的重复模板模式,但我不确定我在这里做什么。

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
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;
};

以及给定事件类型的子类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 );
    }
};

以及实现侦听器类的类:

1
2
3
4
5
6
7
8
9
class MyClass :  public ConnectionSuccessEvent::Listener
{
public:

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

我使用如下:

1
2
3
4
5
6
7
8
9
10
11
12
MyClass oMyClassInstance;

ConnectionSuccessEvent oOnConnectionSuccess;

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

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

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

这会导致几个编译错误,第一个错误是:

错误2错误C2059:语法错误:">"C:deveventstestevent.h 16

对应于向量m的声明。

我有两个问题:

  • 是什么导致了我的错误?我是否不允许在我的类事件中使用EventType::Listener?

  • 奇怪的循环模式是如何可能的?我的意思是,要定义派生类,它需要定义其父类。但由于它是父类,父类要求定义它的模板参数类,即它是基类),所以这是一个问题,因为要定义一个模板参数类,就需要先定义另一个模板参数类。这就像在类B中有一个A的实例,在类A中有一个OB B的实例。

谢谢您!

编辑:我不能使用C++ 11。


我找到了一个可以接受的丑陋的方法!

包含事件对象行为的基本事件类。

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
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 );
    }
};

还有:

1
2
3
4
5
6
7
8
9
template< class EventDataType >
class EventListener
{
public:

    virtual ~EventListener() { }

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

连接成功事件特定内容:

1
2
3
4
5
6
7
8
9
class ConnectionSuccessEventData
{
public:
    const int m_iVal;
    ConnectionSuccessEventData( int iVal ) : m_iVal( iVal ) { }
};

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

数据接收开发特定的内容:

1
2
3
4
5
6
7
8
9
class DataReceivedEventData
{
public:
    const float m_fVal;
    DataReceivedEventData( float fVal ) : m_fVal( fVal ) { }
};

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

侦听器类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
    }
};

用途:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;