簡體   English   中英

如何遍歷 class 模板中的所有類型名?

[英]How to iterate through all typenames in a class template?

我想為我的游戲設計一個基於組件的武器模板。 但是,似乎沒有辦法添加/刪除 class 成員或創建代碼?

對不起我的表達和缺乏術語,因為我沒有從部門畢業。 計算機科學或軟件工程師,我對專業人士所說的那些東西知之甚少。

這是組件代碼的樣子:

class CBaseWpnCmpt : public std::enable_shared_from_this<CBaseWpnCmpt>
{
public:
    typedef std::shared_ptr<CBaseWpnCmpt> PTR;

private:
    CBaseWpnCmpt() = default;

public:
    CBaseWpnCmpt(const CBaseWpnCmpt& s) = default;
    CBaseWpnCmpt(CBaseWpnCmpt&& s) = default;
    CBaseWpnCmpt& operator=(const CBaseWpnCmpt& s) = default;
    CBaseWpnCmpt& operator=(CBaseWpnCmpt&& s) = default;
    virtual ~CBaseWpnCmpt() {}

protected:
    CBaseWeaponInterface::PTR m_pWeapon { nullptr };

public:
    template <class CComponent>
    static std::shared_ptr<CComponent> Create(CBaseWeaponInterface::PTR pWeapon)
    {
        std::shared_ptr<CComponent> pComponent = std::make_shared<CComponent>();
        pComponent->m_pWeapon = pWeapon;
        return pComponent;
    }
};

這就是武器主體代碼的樣子:(問題就出現了)

template <  class CWeapon,
            class ...CComponents
>
class CBaseWeaponTemplate : public CBaseWeaponInterface
{
public:
    std::list<CBaseWpnCmpt::PTR>    m_lstComponents;

public:
    virtual void    SecondaryAttack(void)   // Example method.
    {
        for (auto& pComponent : m_rgpComponents)
        {
            pComponent->SecondaryAttack();
        }
    }
};

我想如何將所有這些參數包創建為模板的成員? 目前我試圖將它們登記到指針 std::list 容器中,但我根本不知道如何實現它。

換句話說,當我填寫空白時如何制作模板,如下所示:

class CAK47 : public CBaseWeaponTemplate<CAK47, CLongMagazine, CWoodenStock>

將生成:

class CAK47
{
    CLongMagazine m_comp1;
    CWoodenStock m_comp2;
//... other stuff
};

或者,生成這個:

class CAK47
{
    CAK47() // constructor
    {
        for (/* somehow iterate through all typenames */)
        {
            CBaseWpnCmpt::PTR p = std::make_shared<typename>();
            m_lstComponents.emplace_back(p);
        }
    }
};

從 C++11 開始的一種方法是將用於此特定武器的模板類型存儲在std::tuple

template <typename Weapon, typename... Attachments>
class WeaponWithAttachments {
  protected:
    WeaponWithAttachments() {
    return;
    }
    std::tuple<Attachments...> attachment_types;
};

然后使用該元組使用受保護的構造函數初始化一個共享指針向量,該構造函數采用一個元組再次訪問模板類型。

class SomeWeaponWithAttachments: public WeaponWithAttachments<SomeWeapon,SomeAttachment,AnotherAttachment> {
  public:
    SomeWeaponWithAttachments()
      : SomeWeaponWithAttachments{attachment_types} {
      return;
    }
  protected:
    template <typename... Attachments>
    SomeWeaponWithAttachments(std::tuple<Attachments...> const&)
      : attachments{std::make_shared<Attachments>()...} {
      return;
    }
    std::vector<std::shared_ptr<BaseAttachment>> attachments;
};

在這里試試!


如果attachments向量已經在父 class 中聲明,就像它似乎是這種情況,您也可以通過初始化父 class 中的附件來避免元組和受保護的構造函數

template <typename Weapon, typename... Attachments>
class WeaponWithAttachments {
  protected:
    WeaponWithAttachments()
      : attachments{std::make_shared<Attachments>()...} {
      return;
    }
    std::vector<std::shared_ptr<BaseAttachment>> attachments;
};

然后只在派生的 class 中調用基礎 class 的構造函數

class SomeWeaponWithAttachments: public WeaponWithAttachments<SomeWeapon,SomeAttachment,AnotherAttachment> {
  public:
    SomeWeaponWithAttachments()
      : WeaponWithAttachments<SomeWeapon,SomeAttachment,AnotherAttachment>() {
      return;
    }
};

在這里試試!


如果這不是您的選擇,那么您可以使用元組使用 C++17 折疊表達式遍歷所有模板 arguments:

class SomeWeaponWithAttachments: public WeaponWithAttachments<SomeWeapon,SomeAttachment,AnotherAttachment> {
  public:
    SomeWeaponWithAttachments()
      : SomeWeaponWithAttachments{attachment_types} {
      return;
    }
  protected:
    template <typename... Attachments>
    SomeWeaponWithAttachments(std::tuple<Attachments...> const&) {
      (attachments.push_back(std::make_shared<Attachments>()), ...);
      return;
    }
};

在這里試試!


在 C++17 中,您還可以在構造函數中添加帶有折疊表達式的 static 斷言,以確保類型實際上繼承自BaseAttachment

static_assert((std::is_base_of_v<BaseAttachment, Attachments> && ...), "Template arguments must inherit from 'BaseAttachment'.");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM