繁体   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