我的一個項目中有很多自定義數據類型,它們都共享一個基類。 我的數據(來自數據庫)有一個數據類型,它通過基類的枚舉進行區分。我的架構允許特定的數據類型專門用於派生類,或者它可以由基類來處理。優化交換機的模板替換
當我構建一個我具體的數據類型,我通常調用構造函數直接:
Special_Type_X a = Special_Type_X("34.34:fdfh-78");
a.getFoo();
有一些模板魔術這也使得構建這樣的:
Type_Helper<Base_Type::special_type_x>::Type a = Base_Type::construct<Base_Type::special_type_x>("34.34:fdfh-78");
a.getFoo();
有關的一些值類型枚舉可能沒有專門化所以
Type_Helper<Base_Type::non_specialized_type_1>::Type == Base_Type
當im從數據庫中獲取數據的數據類型在編譯時間,以便有構造數據類型(從的QVariant)第三條道路稱爲:
Base_Type a = Base_Type::construct(Base_type::whatever,"[email protected]{3,3}");
但當然我想正確的構造函數被調用,所以執行該方法的使用看起來像:
switch(t) {
case Base_Type::special_type_x:
return Base_Type::construct<Base_Type::special_type_x>(var);
case Base_Type::non_specialized_type_1:
return Base_Type::construct<Base_Type::non_specialized_type_1>(var);
case Base_Type::whatever:
return Base_Type::construct<Base_Type::whatever>(var);
//.....
}
此代碼是重複的,因爲基類可以處理新類型(加入到枚舉)爲好,我想出了以下解決方案:
//Helper Template Method
template <Base_Type::type_enum bt_itr>
Base_Type construct_switch(const Base_Type::type_enum& bt, const QVariant& v)
{
if(bt_itr==bt)
return Base_Type::construct<bt_itr>(v);
return construct_switch<(Base_Type::type_enum)(bt_itr+1)>(bt,v);
}
//Specialization for the last available (dummy type): num_types
template <>
Base_Type construct_switch<Base_Type::num_types>(const Base_Type::type_enum& bt, const QVariant&)
{
qWarning() << "Type"<<bt<<"could not be constructed";
return Base_Type(); //creates an invalid Custom Type
}
而且我原來的switch語句替換:
return construct_switch<(Base_Type::type_enum)0>(t,var);
該解決方案按預期工作。然而,編譯後的代碼卻有所不同。儘管最初的開關語句具有O(1)的複雜性,但新的結果導致O(n)複雜性。生成的代碼會遞歸調用我的幫助器方法,直到找到正確的條目。 編譯器爲什麼不能正確地優化它?有沒有更好的方法來解決這個問題?
類似的問題: Replaceing switch statements when interfaceing between templated and non-templated code
我要指出,我想避免C++ 11和C++ 14和堅持C++ 03。
這是一個很好的解決方案!使用C++ 03時我有什麼選擇? – Dreamcooled
@dreamcooled升級您的編譯器,使用chained-'if'語句,使用工具生成代碼,複製麪食,使用預處理器宏生成代碼。 – Yakk
編譯器已升級。完美的作品。謝謝。 – Dreamcooled