簡體   English   中英

C ++編譯類的子類的時間列表

[英]C++ Compile time list of subclasses of a class

我在考慮如何創建一個派生自模板基類的所有類的列表。

首先,我想要一個模板基類:

template <typename T>
class Base
{
public:
    Base() {};
    virtual ~Base() {};
};

和一個繼承自基本模板類的類:

class Foo : public Base<Foo >
{
public:
    Foo () {};
    virtual ~Foo () {};
};

可能有許多其他子類,如Foo 結果看起來應該是這樣的:

std::vector<std::string> allTemplates = Base<Base>::getAllTemplateClasses();

我的問題是,是否可以在編譯時創建所有子類的列表? 魔術應該在基礎課中或在兒童班中付出很少的努力。

我以前在不同的方向思考。 首先我認為可以使用constexpr 像每個子類都需要一個帶簽名的靜態函數:

constexpr static std::string name() { "Foo";}

或者想到也許有可能使用元編程並創建一個編譯時列表, 如編譯時數據結構使用示例,模板元 這里的問題是我不知道模板創建的負責人。

接下來我正在考慮使用宏並構建一個枚舉結構,就像Enum結構擴展一樣 所以我找不到任何解決這個問題的方法我想問你是否可能?

編輯:

說清楚:我想要一個子對象列表,而不需要創建它們。

有了這個很好的帖子靜態構造函數和一個與此類似的已經答案,我能夠找到一個解決方案。 神奇的是靜態構造函數。 首先,我將創建一個容納子類並添加子類的容器:

//base.h
std::set<std::string> &get_objects();
void add_object(const char *name);

實施:

// base.cpp

std::set<std::string> &get_objects()
{
    static std::set<std::string> theSet;
    return theSet;
}

void add_object(const char *name)
{
    get_objects().emplace(name);
}

所以現在我們必須創建一個靜態類,將字符串添加到列表中。 它類似於post 靜態構造函數

//base.h
class StaticClassType {
public:
    StaticClassType(const char *name) {
        // Notify when the static member is created
        add_object(name);
    }
};

基類是一個模板類,它創建一個'StaticClassType'的靜態對象。 C ++保證在調用main()之前完成靜態初始化。

//base.h
template<typename T>
class Base {
protected:
    // Static member in a template class
    static StaticClassType m;
    Base()
    {
        (void)m;
    }
};

沒有下一行, m不會得到createad:

template<typename T>
StaticClassType Base<T>::m = StaticClassType(typeid(T).name());

現在我們可以創建兩個類和主要:

class TestClass1 : public Base<TestClass1> {
public:
    TestClass1() :Base() {}
};

class TestClass1 : public Base<TestClass1> {
public:
    TestClass1() :Base() {}
};

int main()
{
    std::set<std::string> &test = get_objects();
    for(auto str : test)
        std::cout << str.c_str() << std::endl;
    return 0;
}

輸出沒有任何構造任何對象:

class TestClass1
class TestClass2

有人認為要照顧。 我們必須在某個地方使用m 否則編譯器會優化代碼並刪除m 我通過寫入構造函數調用強制執行此行為:

TestClass1() :Base() {}

希望你喜歡它,它不是真正的編譯時間,但我們有對象列表,沒有做任何事情通過編寫構造函數並使用base作為父類。

暫無
暫無

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

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