值键入运行映射

问题描述:

考虑以下代码值键入运行映射

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

https://godbolt.org/g/uBsFD8

我实现了无关typeTag。

你的意思是getDerivedByTag(b->typeTag)而不是getDerivedByTag(b)