如果您想避免手動類型遞歸,std::common_type
在我看來是STL中唯一的實用程序,它是一個可變參數模板,因此它是唯一一個可能封裝遞歸的實用程序。
溶液1
std::common_type
發現在一組類型的至少派生的類型。如果我們用類型來識別數字,特別是具有較少派生類型的高數字,它會找到一組中最大的數字。然後,我們必須將等同關係類型映射到一個推導級別。
using namespace std;
struct base_one { enum { value = 1 }; };
struct derived_zero : base_one { enum { value = 0 }; };
template< typename A, typename B >
struct type_equal {
typedef derived_zero type;
};
template< typename A >
struct type_equal< A, A > {
typedef base_one type;
};
template< typename Key, typename ... Types >
struct pack_any {
enum { value =
common_type< typename type_equal< Key, Types >::type ... >::type::value };
};
解決方案2
我們可以破解common_type
多一點。標準說
如果在 專業化 至少一個模板參數是用戶定義類型的程序可以專門此特徵。
並且準確地描述了它裏面的內容:遞歸部分專業化案例,應用二元運算符的案例和終端案例。實質上,它是一個通用的fold
函數,您可以添加任何二進制操作。這裏我使用了另外,因爲它比OR更具信息性。請注意,is_same
返回integral_constant
。
template< typename Addend >
struct type_sum { // need to define a dummy type to turn common_type into a sum
typedef Addend type;
};
namespace std { // allowed to specialize this particular template
template< typename LHS, typename RHS >
struct common_type< type_sum<LHS>, type_sum<RHS> > {
typedef type_sum< integral_constant< int,
LHS::type::value + RHS::type::value > > type; // <= addition here
};
}
template< typename Key, typename ... Types >
struct pack_count : integral_constant< int,
common_type< type_sum< is_same< Key, Types > > ... >::type::type::value > {};
可能是一個更大的內部操作應該由語言/編譯器支持,而不僅僅是sizeof ....(4個點!)IMO,檢查存在與查找大小一樣是「基礎」。我覺得mpl的性能開銷是基於我寫的這個測試。 http://www.dre.vanderbilt.edu/~sutambe/files/mpl_intersection。cpp 我使用手動編碼的相交算法以及MPL的版本。 g ++ 4.4需要花費相同的時間來編譯兩者。 Variadic模板版本編譯速度提高了10倍。順便說一句,你可以請建議我讀一下關於mpl的懶惰模板實例化技術? – Sumant 2010-01-23 07:17:14
我在C++ Template Metaprogramming書中發現了一些很好的惰性評估示例。這不是很明顯嗎?!不管怎麼說,多謝拉。 – Sumant 2010-01-23 07:25:50
是的,你所要做的就是儘量避免模板實例化元函數(通過暴露嵌套類型別名類型「),然後再將結果提供給另一個增強元函數。Boost元函數設計用於評估元函數在最後一刻需要嵌套類型別名,你也應該嘗試避免使用裸值,並使用元數據類型包裝器(如mpl :: bool_),因爲它們也被設計爲延遲工作。 有時boost mpl提供 – 2010-01-23 10:10:07