2013-07-10 100 views
1

是否有可能編寫一個(內聯?)C++函數,在那裏我們接受一個枚舉作爲輸入並返回一個可以在模板聲明中使用的類類型?C++函數,接受枚舉並返回一個typedef類類型用於模板?

我的直覺是,由於枚舉類型的數量有限,應該有可能嗎?

enum MyEnumType { A, B, C }; 

class MyClassA { }; 
class MyCLassB { }; 
class MyClassB { }; 

template class<T> 
class ATemplatedClass { 
    // ... 
}; 

NotSureWhatReturnType ConvertEnumToClassType(MyEnumType type) { 
    switch (type) { 
    case A: return MyClassA; 
    case B: return MyClassB; 
    case C: return MyClassC: 
    default: throw; 
    } 
} 

MyEnumType type = GottenSomewhere(); 

auto class_type = ConvertEnumToClassType(type); 

ATemplatedClass<class_type> is_this_possible; 
+0

也許你想看看多態的類層次結構和工廠? –

+1

您應該解釋您想解決的**真實**問題,而不是預期的解決方案。你所問的問題不能直接完成,但還有其他的東西可能適合這個問題(例如,從枚舉映射到一個類型的特徵) –

回答

1

使用模板,並專注:

template <MyEnumType> struct ConvertEnum; 

template <> struct ConvertEnum<A> { typedef MyClassA type; }; 
template <> struct ConvertEnum<B> { typedef MyClassB type; }; 
template <> struct ConvertEnum<C> { typedef MyClassC type; }; 

用法:

ConvertEnum<A>::type x; 
+0

如果我錯了,請原諒我,但是這種解決方案只有在類型在編譯時已知?例如,如果枚舉類型是在運行時獲取的,它將無法工作? – user2570384

+1

@ user2570384:好的。這就是爲什麼他們稱C++ *靜態*鍵入。這不僅僅是它不起作用。如果您在編譯時不知道枚舉,那麼整個問題就沒有任何意義。 –

3

函數不能返回類型。你需要一個metafunction

template <MyEnumType> 
struct ConvertEnumToClassType; 

template <> 
struct ConvertEnumToClassType<A> { 
    typedef MyClassA type; 
}; 

template <> 
struct ConvertEnumToClassType<B> { 
    typedef MyClassB type; 
}; 

// … etc. 

typedef ConvertEnumToClassType<A> class_type; 

ATemplatedClass<class_type> is_this_possible; 

當然,這隻能在編譯的時候(因爲當模板解決這)。

1

有幾種方法。

首先,如果您在編譯時知道enum,則可以創建一個以enum作爲模板參數並按照預期返回tyoe的元函數。

如果你不這樣做,有幾種方法。

首先,你可以做一個魔術開關,在那裏你獲得一個仿函數,並用運行時決定的enum值來調用它。有趣的是,最好通過首先實現上述的元函數解決方案來完成。

第二種方法是類型擦除。您返回一個外部統一的對象,但其內部知道它具有特定的類型。作爲例子,boost::variant。現在訪問該內部tyoe可以涉及上述解決方案(boost訪問者喜歡),或者可能是virtualstd::function接口,內部存儲不同的行爲。

最後,您可以通過將運行時enum映射到編譯時間enum(而不是類型)並使用第一種技術來使用魔術切換技術。

魔術開關技術並不是那麼神奇。編寫一個switch語句,並在每種情況下使用類型或編譯時間常量調用模板函子。爲了讓它看起來很花哨,可以將交換機的「主體」作爲模板參數,甚至可以使用一些元編程通過嵌套if或數組查找生成交換機代碼。這些先進技術不是必需的。