如何在具有不同命名空间的派生c++类中初始化模板静态成员

How to initialize template static member in derived C++ class with different namespaces

本文关键字:c++ 初始化 静态成员 派生 命名空间      更新时间:2023-10-16

我有以下基类:

 namespace n1 {
    template <class T, typename A>
    class FSM
    {
      protected:
        typedef void (T::*pfun)();
        typedef std::map<A, pfun > transition_table_t;
        static transition_table_t _transition_table; 
    };
    } // namespace n1

和以下一组宏,用于定义派生类字段

中的静态成员
#define BEGIN_TRANSITION_MAP(class_type, state_type) 
template <>  std::map< state_type, class_type::*pfun >  FSM<class_type, state_type>::_transition_table= {
#define TRANSITION_ENTRY(state, action) 
{state, action},
#define END_TRANSITION_MAP 
};
现在,在另一个cpp文件中,我定义了下一个派生类:
namespace n1{
    namespace n2{
    namespace n3{
    enum state{
        state1,
        state2,
    };
    class derive : public FSM<derive, state>
    {
        friend class FSM<derive, state>;
        void event_a();
        void event_b();
    };
    BEGIN_TRANSITION_MAP(n2::n3::derive, n2::n3::state) 
    TRANSITION_ENTRY(n2::n3::state1, &n2::n3::derive::event_a)
    TRANSITION_ENTRY(n2::n3::state2, &n2::n3::derive::event_b)
    END_TRANSITION_MAP
    }//namespace n3
    }//namespace n2
}//namespace n1

此代码在g++ 4.7c++11下可以正常编译。

我想编写相同的内容,但不需要在派生类中执行基类friend,也不需要在宏中指定所有名称空间。比如:

namespace n1{
    namespace n2{
    namespace n3{
    enum state{
        state1,
        state2,
    };
    class derive : public FSM<derive, state>
    {
        void event_a();
        void event_b();   
    };
    BEGIN_TRANSITION_MAP(derive, state) 
    TRANSITION_ENTRY(state1, &derive::event_a)
    TRANSITION_ENTRY(state2,&derive::event_a)
    END_TRANSITION_MAP
    } //namespace n3
    } //namespace n2
} //namespace n1

这是可能的,还是有更好的方法来解决这个问题?

仅在派生类中定义转换表。然后使用derived::transition_table从基类引用它。这就是所谓的奇怪循环模板模式(谷歌一下)。

template <typename derived>
class FSM
{
public:
  typedef std::map<state_type, event_type> transition_table_t;
  // do not define transition_table here
  void function()
  {
    // use transition table of derived type
    derived::transition_table.do_something();
  }
};
class Derived : public FSM<Derived>
{
public:
  static transition_table_t transition_table;
};