【问题标题】:Having trouble storing a CRTP based class in a vector在向量中存储基于 CRTP 的类时遇到问题
【发布时间】:2010-06-15 02:35:25
【问题描述】:

我不确定这是否可以做到,我只是深入研究模板,所以我的理解可能有点错误。

我有一个士兵排,排继承了一个编队来获取编队属性,但是因为我可以拥有尽可能多的编队,所以我选择使用 CRTP 来创建编队,希望我可以制作一个 Platoon 的向量或数组来存储排。但是,当然,当我制作一个 Platoon 时,它不会将其存储在向量中,“类型不相关”

有没有办法解决这个问题?我读到了类似的“单板”,它们与数组一起工作,但我无法让它工作,也许我错过了一些东西。

这里有一些代码:(对不起格式,代码在我的帖子中,但由于某种原因它没有显示)

template < class TBase >
class IFormation 
{
public : 
~IFormation(){}

bool IsFull()
{
    return m_uiMaxMembers == m_uiCurrentMemCount;
}
protected:
    unsigned int m_uiCurrentMemCount;
    unsigned int m_uiMaxMembers;
    IFormation( unsigned int _uiMaxMembers  ): m_uiMaxMembers( _uiMaxMembers ), m_uiCurrentMemCount( 0 ){}      // only allow use as a base class.

    void SetupFormation( std::vector<MySoldier*>& _soldierList ){}; // must be implemented in derived class
};
/////////////////////////////////////////////////////////////////////////////////
// PHALANX FORMATION
class Phalanx : public IFormation<Phalanx>
{
public:
Phalanx( ):
  IFormation( 12 ),
  m_fDistance( 4.0f )
{}

~Phalanx(){}


protected:
float   m_fDistance;        // the distance between soldiers
void    SetupFormation( std::vector<MySoldier*>& _soldierList );
};
///////////////////////////////////////////////////////////////////////////////////
// COLUMN FORMATINO
class Column : public IFormation< Column >
{
public :
Column( int _numOfMembers ):
   IFormation( _numOfMembers )
   {}

~Column();
protected:
void    SetupFormation( std::vector<MySoldier*>& _soldierList );
};

然后我在 platoon 类中使用这些编队进行推导,让 platoon 得到相关的 SetupFormation() 函数:

template < class Formation >
class Platoon : public Formation
{
public:
**** platoon code here
};

到目前为止,一切都很好,并且符合预期。

现在,由于我的将军可以有多个排,我需要存储这些排。

typedef Platoon< IFormation<> > TPlatoon; // FAIL
typedef std::vector<TPlatoon*>  TPlatoons;
TPlatoon            m_pPlatoons

m_pPlatoons.push_back( new Platoon<Phalanx> ); // FAIL, types unrelated.

typedef Platoon > TPlatoon;失败是因为我需要指定一个模板参数,但指定它只会让我存储使用相同模板参数创建的排。

于是我创建了 FormationBase

class FormationBase
{
public:
    virtual bool IsFull() = 0;
    virtual void SetupFormation( std::vector<MySoldier*>& _soldierList ) = 0;
};

并让 IFormation 公开继承,然后将 typedef 更改为

typedef Platoon< IFormation< FormationBase > > TPlatoon;

但仍然没有爱。

现在在我的搜索中,我没有找到表明这是可能或不可能的信息。

【问题讨论】:

  • 不要在帖子中使用 或 <pre> 标签——它们不会按照您对 SO 的期望进行。</pre>
  • 你为什么使用 CRTP?我在任何地方都没有看到 IFormation 使用它的派生类类型...
  • 我认为这是我试图使用多种方法来获得我想要的东西的产物。我想我最终得到了“单板”而不是 CRTP...

标签: c++ storage containers crtp


【解决方案1】:

C++ 不允许简单地使用编译时和运行时多态性。您是正确的,因为您的向量只能容纳一种类型。您将不得不让您的向量存储一个指向非模板类型的指针,或者将设计更改为不使用向量。

如果您想让 CRTP 的类公开继承自 FormationBase,则向量必须是 std::vector&lt;FormationBase *&gt;。不可能从运行时类 FormationBase 回到它被实例化的编译时模板参数。

考虑到您的数据看起来相对一致,而您只想更改算法在战场上安排士兵和单位的方式,我会考虑使用策略模式来指定 SetupFormation 函数,并使用该函数创建一个单独的非多态类存储在向量中。

【讨论】:

  • 谢谢,我已经按照你的建议改变了使用“策略模式”,它达到了我想要的效果。感谢您提供有关策略模式的提示。自我提醒:当时间至关重要时,不要尝试实施不熟悉的模式;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 2011-08-23
  • 2020-06-17
  • 2020-10-07
  • 2022-01-20
相关资源
最近更新 更多