2016-04-26 92 views
1

考慮以下代碼值鍵入運行映射

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值在運行時恢復派生類型參數?顯然,需要一些外部初步準備的映射,但我無法弄清楚確切的方法。

回答

0

你想要的基本上是一個reflection,它還沒有在C++中支持。有很多方法可以模擬它或者解決它,但它們通常冗長而不優雅。我會建議重新考慮你的設計,特別是你使用auto。它不應該代替您的代碼所暗示的「任何類型」。當實際類型很長或模糊時(通常發生在模板中),嵌套等等時,它的意思是簡化代碼。不是當你不知道類型時!因爲那麼你不能真正使用它,你能嗎。

所以你需要做的是以這種或那種方式直接檢查typeTag並繼續根據這些信息。或者,您需要直接使用Base使用多態(調用虛擬方法傳播到Derived)。對於類型聯合,你可以使用boost::variant(如果你不關心Derived模板參數是什麼類型的話)或者Qt中的QVariant之類的其他框架/庫替代。

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)