值键入运行映射
问题描述:
考虑以下代码值键入运行映射
enum Types
{
t1,
t2
};
struct Base
{
Types typeTag;
Base(Types t) : typeTag(t){}
};
template<typename T>
struct Derived : Base
{
using Base::Base;
T makeT() { return T(); }
};
int main()
{
Base *b = new Derived<std::string>(t1);
auto d = getDerivedByTag(b); // How ??
d->makeT();
return 0;
}
是否有可能通过基地:: typeTag值在运行时恢复派生类型参数?显然,需要一些外部初步准备的映射,但我无法弄清楚确切的方法。
答
你想要的基本上是一个reflection,它还没有在C++中支持。有很多方法可以模拟它或者解决它,但它们通常冗长而不优雅。我会建议重新考虑你的设计,特别是你使用auto
。它不应该代替您的代码所暗示的“任何类型”。当实际类型很长或模糊时(通常发生在模板中),嵌套等等时,它的意思是简化代码。不是当你不知道类型时!因为那么你不能真正使用它,你能吗。
所以你需要做的是以这种或那种方式直接检查typeTag
并继续根据这些信息。或者,您需要直接使用Base
使用多态(调用虚拟方法传播到Derived
)。对于类型联合,你可以使用boost::variant
(如果你不关心Derived
模板参数是什么类型的话)或者Qt中的QVariant
之类的其他框架/库替代。
答
我不确定我的理解是否正确。
#include "iostream"
enum Types
{
t1,
t2
};
template<typename T>
struct Base
{
typedef T DerivedType;
Types typeTag;
Base(Types t) : typeTag(t){}
DerivedType* operator()() {
return static_cast<DerivedType*>(this);
}
};
template<typename T>
struct Derived : Base<Derived<T>>
{
Derived(Types t): Base<Derived<T>>(t) {}
T makeT() { return T(); }
};
int main()
{
Base<Derived<std::string>> *b = new Derived<std::string>(t1);
auto d = (*b)();
d->makeT();
return 0;
}
我实现了无关typeTag。
你的意思是getDerivedByTag(b->typeTag)
而不是getDerivedByTag(b)
?