gpt4 book ai didi

c++ - 如何维护从基类派生的所有类型的编译时列表?

转载 作者:行者123 更新时间:2023-11-30 04:02:28 24 4
gpt4 key购买 nike

关于为 c# 维护类型的运行时列表,有人提出了类似的问题:

How can I store and use an array of different types derived from a common base type?

基本上我想要的是维护从公共(public)基类派生的类型名称序列。我可以通过执行以下操作在运行时实现此目的:

std::vector v;

template <typename Derived>
class Base
{
Base() { v.push_back(typeid(Derived).name())
};

如果所有派生类都是单例,这会起作用,但会产生运行时开销。如果他们不是单例,我可以添加一些检查以避免重复,但它仍然涉及运行时成本。我正在考虑改为填充类型序列,例如 boost::mpl_vector:

class Derived1 : public Base<Derived1> {}
class Derived2 : public Base<Derived2> {}
class Derived3 : public Base<Derived3> {}

typedef boost::mpl::vector<
Derived1,
Derived2,
Derived3> TypeSequence;

这行得通,但这意味着我必须手动维护列表,这对很多类型来说都是一件麻烦事。我知道我可以使用 boost 预处理器 循环的可怕组合来自动执行此过程,但我希望避免宏以尽可能保持代码库的可维护性。

有什么建议吗?

编辑:解决方案必须完全是编译时的,并且即使没有实例化任何类型也必须有效。

最佳答案

注意:这个答案是在“解决方案必须完全是编译时的,并且即使没有任何类型被实例化的情况下也必须工作”之前写的。已添加到问题中。


虽然这不是在编译时计算的,但是每个类型的名称只加一次。您必须为每种类型至少创建一个实例才能工作(又名。未实例化的类型将不会添加到容器中)

#include <iostream>
#include <vector>
#include <string>

struct TypeBase{
static std::vector<std::string> m_container;
};

std::vector<std::string> TypeBase::m_container;

template <typename DerivedType>
struct MyBase{
MyBase(){
static bool typeAdded = false;
if(!typeAdded){
typeAdded = true;
// you may also want to demangle this name
// take a look at boost/units/detail/utility.hpp
TypeBase::m_container.push_back(typeid(DerivedType).name());
}
}
};

struct Derived1 : public MyBase<Derived1>{

};

struct Derived2 : public MyBase<Derived2>{

};

struct Derived3 : public MyBase<Derived3>{

};

int main(){
Derived1 a, b, c;
Derived2 d, e, f;
Derived3 g, h, i;

for(std::string const & name : TypeBase::m_container){
std::cout << name << std::endl;
}

std::cin.get();
}

使用我的编译器打印:

struct Derived1
struct Derived2
struct Derived3

关于c++ - 如何维护从基类派生的所有类型的编译时列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25049549/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com