TL; DR:寻找一个预处理器宏来为所有预定义集合的组合生成所有if/else-if/else-error
语句/模板参数的枚举。C++在运行时从编译时间已知设置/枚举中选择模板非类型参数
我有一个抽象类(Base
)3-亚类(SubA<int a>
,SubB<int a>
,SubC<int a, int b>
),所以无法初始化抽象类,但可以初始化子类。这些子类也有一个或两个非类型的模板参数。我有一个基准测试工具,它从数据库(子类运行,模板参数和参数/工作负载)拉出不同的基准测试配置。模板参数是确定性集合(a in {256, 512, 1024, 2048, 4096, 8192, 16384}
和b in {1, 2, 3}
)。
我希望能够将Base
对象作为具有正确模板参数的子类实例化,而不必使用所有可能性/组合的if/else if
。有没有一种干净的方法在C++中执行此操作,无论是使用枚举,数组还是预处理器宏?
一个冗长的方法会有很多if-else语句,但我想要一个更干净的解决方案,如果可能的话,将值从枚举,集合或数组中抽出。当然,有一种生成组合的预处理方式,或者是一种从枚举中选择出来的方式(因此编译器创建了所有枚举组合的类)?
Base *base = nullptr;
if (sub == "SubA") {
if (a == 512) {
if (b == 1) {
base = new SubA<512, 1>();
} else if (b == 2) {
base = new SubA<512, 2>();
} else if (b == 3) {
base = new SubA<512, 3>();
}
} else if (a == 1024) {
// ...
}
} else if (sub == "SubB") {
// ...
} else if (sub == "SubC") {
// ...
}
if (base == nullptr) {
throw std::exception();
}
作为进一步的解释,这里是写在JS同等解决方案:
class Base = {...};
function SubAFactory(a, b) = {return class SubA {... definition ...}};
function SubBFactory(a, b) = {return class SubB {... definition ...}};
function SubCFactory(a, b) = {return class SubC {... definition ...}};
const SubFactories = {
SubA: SubAFactory,
SubB: SubBFactory,
SubC: SubCFactory
};
function BaseFactory(sub, a, b) {
// NOTE: an if-else between subclasses would also be fine
// as long as the template args are "dynamic".
return SubFactories[sub](a, b);
}
// retrieved from db at runtime, a and b values will
// always be part of a finite set known at compile time
const dbResult = {sub: 'SubA', a: 2048, b: 2};
const sub = dbResult.sub;
const a = dbResult.a;
const b = dbResult.b;
const base = new BaseFactory(sub, a, b)(/* class constructor args */);
你可以用”在运行时不做与模板相关的任何事情,这是一个仅编译时的功能。 –
你可以但它需要一个非常非常大的开关。编辑:取决于可能的模板实例化的数量,它可以用黑魔法(宏)来完成,但你可能想要找到另一个解决方案 – Nyashes
但是我知道编译时所有可能的值,所以编译器必须有一种方法从一个集合中提取这些可能的值并为这些排列创建类?或者在预处理器宏中做一个体面的方法? –