在向量中存储基于 CRTP 的类时遇到问题

发布于 2024-09-05 16:01:39 字数 2522 浏览 11 评论 0原文

我不确定这是否可以完成,我只是钻研模板,所以也许我的理解有点错误。

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

有什么办法解决这个问题吗?我读到了有关“Veneers”的内容,它们很相似,并且它们与数组一起使用,但我无法让它工作,也许我错过了一些东西。

这是一些代码:(对格式感到抱歉,代码在我的帖子中,但由于某种原因没有显示)

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

然后我在排类中使用这些编队来派生,以便排获得相关的 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 排< IFormation<> > TP排;失败是因为我需要指定一个模板参数,但指定它只允许我存储使用相同模板参数创建的排。

所以我然后创建了 FormationBase

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

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

typedef Platoon< IFormation< FormationBase > > TPlatoon;

但仍然没有爱。

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

Im not sure if this can be done, im just delving into templates so perhaps my understanding is a bit wrong.

I have a Platoon of soldiers, the platoon inherits from a formation to pick up the formations properties, but because i could have as many formations as i can think of I chose to use the CRTP to create the formations, hoping that i could make a vector or array of Platoon to store the platoons in. but, of course, when i make a Platoon, it wont store it in the vector, "types are unrelated"

Is there any way around this ? i read about "Veneers" which are similar and that they work with arrays but i cant get it to work, perhaps im missing something.

here's some code: (sorry about the formatting, the code is here in my post but its not showing up for some reason )

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

I then use these formations in the platoon class to derive, so that platoon gets the relevant SetupFormation() function:

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

everything works great and as expected up until this point.

now, as my general can have multiple platoons, I need to store the platoons.

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< IFormation<> > TPlatoon; fails because i need to specify a template parameter, yet specifying this will only allow me to store platoons created with the same template parameter.

so i then created FormationBase

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

and made IFormation publicly inherit from that, and then changed the typedef to

typedef Platoon< IFormation< FormationBase > > TPlatoon;

but still no love.

now in my searches i have not found info that says this is possible - or not possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

許願樹丅啲祈禱 2024-09-12 16:01:39

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

如果您希望 CRTP 类公开继承自 FormationBase,则向量必须是 std::vector。不可能从运行时类 FormationBase 返回到实例化它所用的编译时模板参数。

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

C++ does not allow simple use of compile time and run time polymorphism. You are correct in that your vector is only able to hold one type. You're going to have to have your vector store a pointer to a non template type, or change the design to not use a vector.

If you want to have the CRTP'd classes publicly inherit from FormationBase, then the vector would have to be a std::vector<FormationBase *>. It's impossible to go back from the runtime class FormationBase to the compile time template parameters it was instantiated with.

Considering your data looks relatively consistent and you merely want to change how your algorithm arranges the soldiers and units on the battlefield, I'd consider using the strategy pattern to specify the SetupFormation function, and have a separate, nonpolymorphic class using that which you store in the vector.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文