考虑这段代码
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;
}
是否可以在运行时通过Base :: typeTag值恢复Derived类型参数?显然,需要一些外部初步准备的映射,但我无法弄清楚确切的方法。
答案 0 :(得分:0)
你想要的基本上是C ++中尚未支持的reflection。有一些方法可以模拟它或解决它,但它们通常是冗长而不优雅的。我建议重新考虑你的设计,尤其是你对auto
的使用。它不应该替代&#34;任何类型&#34;正如你似乎暗示你的代码。它意味着当实际类型很长或模糊(通常发生在模板中),嵌套等时代码的简化。当你不知道类型时!因为那时你无法真正使用它,可以吗。
因此,您需要以某种方式做的事情是直接检查typeTag
并继续根据该信息。或者,您需要直接使用Base
使用多态(调用虚拟方法传播到Derived
)。对于类型联合,您可以使用boost::variant
(如果您不关心类型Derived
模板参数是什么)或者其他一些框架/库替代方案,例如Qt中的QVariant
。
答案 1 :(得分:0)
我不确定我的理解是否正确。
#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)
吗?