C++14 SFINAE 容器类value_type类型提升

C++14 SFINAE 容器类value_type类型提升

原问题:

已知容器类模板Container及其value_type类型,返回容器类类型Container2,将原value_type按如下规则提升:

  • boolshort intintlong intlong long int,提升为long long int
  • floatdoublelong 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设施,负责按照规则提升给定类型。

PromotionTypePromotion的对外接口。

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:

-

原文链接: https://www.cnblogs.com/activa/p/6361465.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/248642

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午3:03
下一篇 2023年2月14日 上午3:05

相关推荐