2

I have the following code (simplified to highlight the current problem):

template <class ENUM_EVENTS>
class CFiniteStateEventBase {};
template <class DATA,class ENUM_STATES,class ENUM_EVENTS>
class CFiniteStateCursor {};
template <class DATA,class ENUM_STATES,class ENUM_EVENTS>
class CFiniteStateBase {};

template <class DATA,class ENUM_STATES,class ENUM_EVENTS>
class CFiniteStateTransitionBase
{
protected:
  CFiniteStateBase<DATA,ENUM_STATES,ENUM_EVENTS> * m_pfsbTo;
public:
  CFiniteStateTransitionBase(CFiniteStateBase<DATA,ENUM_STATES,ENUM_EVENTS> * pfsbTo)
    : m_pfsbTo(pfsbTo) {}

  virtual ~CFiniteStateTransitionBase() {}

  virtual int VTransition() = 0;
};

template <class DATA,class ENUM_STATES,class ENUM_EVENTS>
class CFiniteStateYesTransition
  : public CFiniteStateTransitionBase<DATA,ENUM_STATES,ENUM_EVENTS>
{
public:
  CFiniteStateYesTransition(CFiniteStateBase<DATA,ENUM_STATES,ENUM_EVENTS> * pfsbTo)
    : CFiniteStateTransitionBase<DATA,ENUM_STATES,ENUM_EVENTS>(pfsbTo) {}

  virtual int VTransition()
  {
    m_pfsbTo = 0;
    return 0;
  }
};

It compiles fine on MSVC (6 and 2012) but wit GCC (3.4.6 and 4.1.2 on CentOS 5.10) I get the following error:

fsb.cpp: In member function ‘virtual int CFiniteStateYesTransition::VTransition(CFiniteStateEventBase, DATA, CFiniteStateBase, CFiniteStateBase*, CFiniteStateCursor)’: fsb.cpp:33: erreur: ‘m_pfsbTo’ was not declared in this scope

What is wrong with the declaration of m_pfsbTo?

gregseth
  • 12,952
  • 15
  • 63
  • 96
  • 4
    MSVC is wrong. You need `this->m_pfsbTo`. See http://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data – juanchopanza Apr 04 '14 at 15:18

1 Answers1

3

change m_pfsbTo to

CFiniteStateTransitionBase<DATA,ENUM_STATES,ENUM_EVENTS>::m_pfsbTo

within the virtual function.

Scott Meyers addresses the problem in item 43 of Effective C++ from which I quote:

The problem is that when compilers encounter the definition for the class template LoggingMsgSender, they don't know what class it inherits from. Sure, it's MsgSender<Company>, but Company is a template parameter, one that won't be known until later (when LoggingMsgSender is instantiated). Without knowing what Company is, there's no way to know what the class MsgSender<Company> looks like. In particular there's no way to know if it has a sendClear function.

Modulo the names, this applies perfectly to your case.

Stefano Falasca
  • 8,837
  • 2
  • 18
  • 24