简体   繁体   English

转发声明一个模板化的 typedef

[英]Forward declare a templated typedef

In my public header, I am trying to add a pointer to an object which is only defined privately.在我的公共 header 中,我试图添加一个指向仅私下定义的 object 的指针。 Normally that would be simple.通常这很简单。 I just forward-declare.我只是转发声明。 However, the object is a bit complicated and I'm not sure how to forward declare it.但是,object 有点复杂,我不确定如何转发声明它。

public.h:公共.h:

#include <memory>
class StateMachine; // This forward declaration doesn't work

class MyClass {
    std::unique_ptr<StateMachine> sm_;
public:
    MyClass();
}

public.cpp公共.cpp

#include <public.h>
#include "statemachine.h" //StateMachine declared in full here
MyClass::MyClass 
  : obj_(std::make_unique<StateMachine>(*this)) 
{ 
}

statemachine.h:状态机.h:

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine.hpp>
class MyClass; 

struct _StateMachine : public boost::msm::front::state_machine_def<_StateMachine>
{
    MyClass parent_;
public:
    _StateMachine(MyClass& p_parent);
};

typedef boost::msm::back::state_machine<_StateMachine> StateMachine;

where boost::msm::back::state_machine is defined as:其中boost::msm::back::state_machine定义为:

template <
      class A0
    , class A1 = parameter::void_
    , class A2 = parameter::void_
    , class A3 = parameter::void_
    , class A4 = parameter::void_
>
class state_machine { ... };

Here are some of the forward-declarations I've tried and their error messages (g++)以下是我尝试过的一些前向声明及其错误消息 (g++)

class StateMachine;

error: conflicting declaration 'typedef class boost::msm::back::state_machine<_StateMachine> StateMachine'错误:声明冲突'typedef class boost::msm::back::state_machine<_StateMachine> StateMachine'

namespace boost{ namespace msm { namespace back { class state_machine; }}}
typedef boost::msm::back::state_machine StateMachine;

error: 'boost::msm::back::state_machine' is not a template错误:'boost::msm::back::state_machine' 不是模板

namespace boost{ namespace msm { namespace back { template <class T> class state_machine; }}}
class _StateMachine;
typedef boost::msm::state_machine<_StateMachine> StateMachine;

error: wrong number of template arguments (5, should be 1)错误:模板编号错误 arguments (5, 应该是 1)

namespace boost{ namespace msm { namespace back { template<class T0, class T1, class T2, class T3, class T4> class state_machine; }}}
class _StateMachine;
typedef boost::msm::back::state_machine<_StateMachine> StateMachine;

error: error: wrong number of template arguments (1, should be 5) error: error: 错误的模板编号 arguments (1, 应该是 5)

namespace boost{ namespace msm { namespace back { template<class T0, class T1, class T2, class T3, class T4> class state_machine; }}}
class _StateMachine;
class Void;
typedef boost::msm::back::state_machine<_StateMachine, Void, Void, Void, Void> StateMachine;

error: conflicting declaration 'typedef class boost::msm::back::state_machine<_StateMachine> StateMachine'错误:声明冲突'typedef class boost::msm::back::state_machine<_StateMachine> StateMachine'

If you really don't want to include boost/msm/back/state_machine.hpp , then you need to forward-declare state_machine and use it correctly.如果您真的不想包含boost/msm/back/state_machine.hpp ,那么您需要转发声明state_machine并正确使用它。

Your attempt fails because T1 , T2 , T3 , and T4 are not given a type when instantiated.您的尝试失败,因为T1T2T3T4在实例化时未指定类型。

namespace boost{ namespace msm { namespace back { template<class T0, class T1, class T2, class T3, class T4> class state_machine; }}}
class _StateMachine;
typedef boost::msm::back::state_machine<
    _StateMachine
    /* need types here, we don't know there are default ones defined later */
> StateMachine;

Your attempt with class Void;您对class Void; fails because Void is not parameter::void_ , so the two typedefs are different.失败是因为Void不是parameter::void_ ,所以这两个 typedef 是不同的。

Note before the solution: in C++, you should probably use using instead of typedef .在解决方案之前注意:在 C++ 中,您可能应该使用using而不是typedef Also, in C++17, you can do namespace boost::msm::back {... } .此外,在 C++17 中,您可以执行namespace boost::msm::back {... }

The solution is to forward declare parameter::void_ as well and use it in the alias definition.解决方案是也转发 declare parameter::void_并在别名定义中使用它。

namespace boost::msm::back {
namespace parameter {
    // careful, this might be in a different namespace if there is a using namespace somewhere.
    class void_;
}
template<class T0, class T1, class T2, class T3, class T4> class state_machine;
}

class _StateMachine;
using StateMachine = boost::msm::back::state_machine<
    _StateMachine,
    boost::msm::back::parameter::void_,
    boost::msm::back::parameter::void_,
    boost::msm::back::parameter::void_,
    boost::msm::back::parameter::void_
>;

Demo演示

Unfortunately, you cannot provide T1 through T4 with default types because you cannot have multiple declarations of the default parts of template parameter lists, even if they match.不幸的是,您不能为T1T4提供默认类型,因为您不能对模板参数列表的默认部分进行多次声明,即使它们匹配。

I don't see any other solution than this or including the boost header.除了这个或包括提升 header 之外,我没有看到任何其他解决方案。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM