Возникли проблемы при сохранении класса на основе CRTP в векторе - PullRequest
2 голосов
/ 15 июня 2010

Я не уверен, что это можно сделать, я просто углубляюсь в шаблоны, так что, возможно, мое понимание немного неправильное.

У меня есть Взвод солдат, взвод наследует от формирования, чтобы подобрать свойства формаций, но, поскольку у меня может быть столько соединений, сколько я могу себе представить, я решил использовать 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 Взвод > TPlatoon; не удается, потому что мне нужно указать параметр шаблона, но указав это, я могу хранить только взводы, созданные с тем же параметром шаблона.

поэтому я создал FormationBase

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

и сделал публичное наследование IFormation от этого, а затем изменил typedef на

typedef Platoon< IFormation< FormationBase > > TPlatoon;

но все еще нет любви.

сейчас в моих поисках я не нашел информацию, которая говорит, что это возможно - или не возможно.

1 Ответ

2 голосов
/ 15 июня 2010

C ++ не позволяет просто использовать время компиляции и полиморфизм времени выполнения.Вы правы в том, что ваш вектор может содержать только один тип.Вам нужно будет, чтобы ваш вектор сохранял указатель на не шаблонный тип, или измените дизайн так, чтобы не использовать вектор.

Если вы хотите, чтобы классы CRTP публично наследовали от FormationBase, тогда вектор должен быть std::vector<FormationBase *>.Невозможно вернуться из класса времени выполнения FormationBase к параметрам шаблона времени компиляции, с которыми он был создан.

Учитывая, что ваши данные выглядят относительно непротиворечивыми, и вы просто хотите изменить то, как ваш алгоритм размещает солдат и части на поле бояЯ хотел бы использовать шаблон стратегии для указания функции SetupFormation и иметь отдельный неполиморфный класс, использующий тот, который вы храните в векторе.

...