键入运行时映射的值

时间:2016-04-26 18:20:02

标签: c++ templates inheritance

考虑这段代码

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类型参数?显然,需要一些外部初步准备的映射,但我无法弄清楚确切的方法。

2 个答案:

答案 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;
}

https://godbolt.org/g/uBsFD8

我的实现与typeTag无关。

您的意思是getDerivedByTag(b->typeTag)而不是getDerivedByTag(b)吗?