C++14 SFINAE 容器类value_type类型提升
2018-06-17 23:21:38来源:未知 阅读 ()
C++14 SFINAE 容器类value_type类型提升
原问题:
已知容器类模板Container及其value_type类型,返回容器类类型Container2,将原value_type按如下规则提升:
- bool,short int,int,long int,long long int,提升为long long int
- float,double,long double,提升为long double
- default,保持value_type不变
正文:
根据原问题易得如下结构:
template <???> ??? TypePromotion ???; template <class T> using Promotion = ??? TypePromotion ???; template <template <class> class Container, class T> struct ContainerPromotion { using Type = Container<Promotion<T> >; };
注解:
TypePromotion为一个待实现的type_traits设施,负责按照规则提升给定类型。
Promotion为TypePromotion的对外接口。
ContainerPromotion通过Promotion来定义提升后的容器类类型。
其中TypePromotion需要找出给定类型所属的集合,并定义提升后类型。
如何判断给定类型T是否属于某个类型的集合?
将类型集合作为模板类型参数包,递归展开该类型包。在递归的每一层判断目标类型T与当前类型U是否相同,递归返回判断结果的累计或。
template <class T> constexpr bool Any() { return false; } template <class T, class U, class... Types> constexpr bool Any() { return std::is_same<T, U>::value || Any<T, Types...>(); }
如何根据判断结果得到提升后的类型?
用std::enable_if_t来启用特定的模板,并通过该模板定义提升后的类型。对于default情况,可以类型集合的补集来实现或降低其重载决策等级。
这里采用函数模板来实现(由于Promotion系列函数模板只出现在decltype表达式中,故不需要定义):
// integer type template <class T> std::enable_if_t<Any<T, bool, short, int, long int, long long int>(), long long int> Promotion(int); // float type template <class T> std::enable_if_t<Any<T, float, double, long double>(), long double> Promotion(int); // default template <class T> T Promotion(...); // sugar template <class T> using type_promotion_t = decltype(Promotion<T>(0));
完整代码(含测试样例):
1 #include <type_traits> 2 3 template <class T> 4 constexpr bool Any() { 5 return false; 6 } 7 8 template <class T, class U, class... Types> 9 constexpr bool Any() { 10 return std::is_same<T, U>::value || Any<T, Types...>(); 11 } 12 13 // integer type 14 template <class T> 15 std::enable_if_t<Any<T, bool, short, int, long int, long long int>(), 16 long long int> Promotion(int); 17 18 // float type 19 template <class T> 20 std::enable_if_t<Any<T, float, double, long double>(), 21 long double> Promotion(int); 22 23 // default 24 template <class T> 25 T Promotion(...); 26 27 // sugar 28 template <class T> 29 using type_promotion_t = decltype(Promotion<T>(0)); 30 31 template <template <class> class Container, class T> 32 struct ContainerPromotion { 33 using Type = Container<type_promotion_t<T> >; 34 }; 35 36 // Container class template for testing 37 template <class T> 38 class Vector {}; 39 40 int main() { 41 using Type1 = typename ContainerPromotion<Vector, int *>::Type; 42 static_assert(std::is_same<Type1, Vector<int *> >::value, ""); 43 44 using Type2 = typename ContainerPromotion<Vector, short>::Type; 45 static_assert(std::is_same<Type2, Vector<long long int> >::value, ""); 46 47 using Type3 = typename ContainerPromotion<Vector, float>::Type; 48 static_assert(std::is_same<Type3, Vector<long double> >::value, ""); 49 50 return 0; 51 }
FAQ:
-
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- STL之map 2020-04-27
- C++中自定义结构体或类作为关联容器的键 2020-03-15
- 向量容器vector操作 2020-02-03
- C++ STL容器 2019-12-19
- STL源码剖析——序列式容器#5 heap 2019-11-07
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash