前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >现代C++之模板元编程(今天写个If与While)

现代C++之模板元编程(今天写个If与While)

作者头像
公众号guangcity
发布2020-02-13 11:45:27
1K0
发布2020-02-13 11:45:27
举报
文章被收录于专栏:光城(guangcity)

现代C++之模板元编程(今天写个If与While)

0.导语

今天就放轻松,有可能代码写的看的很晦涩,自己多敲几遍即可,下面来进入正文,如何使用模板元编程实现IF与WHILE。

1.IF实现

我们想要的目标如下:

代码语言:javascript
复制
// 加减
template<bool cond, int nums1, int nums2>
struct addSub {
    static const auto RES = IF<cond, Add_<nums1, nums2>, Sub_<nums1, nums2>>::result::value;
};
// 调用
cout << addSub<true, 10, 2>::RES << endl;

当IF条件成立就将两数相加,否则两数相减,就是IF...Then...Else...的逻辑。

首先声明一个空的结构体:

代码语言:javascript
复制
template<bool cond,
        typename Then,
        typename Else>
struct IF;

我们想一下,当IF中的cond条件成立,是不是输出结果就是Then,否则结果就是Else,因此我们只需要获取这两个即可呗。

因此,引出两个偏特化版本:

  • 条件成立
代码语言:javascript
复制
template<typename Then,
        typename Else>
struct IF<true, Then, Else> {
    typedef Then result;
};
  • 条件失败
代码语言:javascript
复制
template<typename Then,
        typename Else>
struct IF<false, Then, Else> {
    typedef Else result;
};

这个搞定了,现在就简单了,编写Then是什么,Else是什么不就得了,因此又得到:

代码语言:javascript
复制
template<int nums1, int nums2>
struct Add_ {
    static const int value = nums1 + nums2;
};

template<int nums1, int nums2>
struct Sub_ {
    static const int value = nums1 - nums2;
};

最后我们一封装,就是下面这个:

代码语言:javascript
复制
template<bool cond, int nums1, int nums2>
struct addSub {
    static const auto RES = IF<cond, Add_<nums1, nums2>, Sub_<nums1, nums2>>::result::value;
};

然后一调用:

代码语言:javascript
复制
addSub<true, 10, 2>::RES

我们的模板实现IF就完成了,哈哈~

除此之外,也可以编写其他需求:

例如:判断输入的数的奇偶性。

代码语言:javascript
复制
// 判断奇数与偶数
template<int N>
struct isEven {
    static const auto RES = IF<N & 1 == 0, true_type, false_type>::result::value;
};

调用:

代码语言:javascript
复制
cout << isEven<10>::RES << endl;

2.WHILE实现

有了IF,WHILE就水到渠成。

原理是一毛一样!

例如:求0~n的和。

代码语言:javascript
复制
template<int n>
struct Sum {
    typedef SumLoop<0, n> type;
};
// 调用
cout << While<Sum<6>::type>::type::value << endl;

因此编写While就成了关键。里面的Sum是判断的条件。

故模仿IF编写,我们先声明一个WhileLoop:

代码语言:javascript
复制
template<bool condition,
        typename Body>
struct WhileLoop;

紧接着,两个偏特化:

  • 条件成立
代码语言:javascript
复制
template<typename Body>
struct WhileLoop<true, Body> {
    typedef typename WhileLoop<
            Body::cond_value,
            typename Body::next_type>::type
            type;
};

此处需要注意:针对while来说,条件成立后,是不断的循环,直到条件不满足,因此这里的true取Body的cond_value成员,而body取Body的next_type,在之后编写循环条件的时候,需要包含这两个。

  • 条件否定
代码语言:javascript
复制
template<typename Body>
struct WhileLoop<false, Body> {
    typedef
    typename Body::res_type type;
};

直接把Body的res_type进行返回,便是最后的结果。

最后,编写循环所需的内容:

代码语言:javascript
复制
template<int result, int n>
struct SumLoop {

    // 循环的条件
    static const bool cond_value =
            n != 0;

    // 循环后的结果
    static const int res_value =
            result;

    // 循环时的状态
    typedef my::integral_constant<
            int, res_value>
            res_type;

    // 循环执行一次时的状态
    typedef SumLoop<result + n, n - 1>
            next_type;
};

这里integral_constant可以是自己写的,也可以是std里面的。

代码语言:javascript
复制
namespace my {
    template<class T, T v>
    struct integral_constant {
        static const T value = v;
        typedef T value_type;
        typedef integral_constant<T, v> type;
    };
}

integral_constant就是对模板参数进行了重新命名,非常简单。

然后,调用:

代码语言:javascript
复制
cout << While<Sum<6>::type>::type::value << endl;

在C++14之后,有了下面语法,因此上述调用可以被简化:

代码语言:javascript
复制
template<int n>
using Sum_t = SumLoop<0, n>;
// 调用
cout << While_t<Sum_t<6>>::type::value << endl;
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 现代C++之模板元编程(今天写个If与While)
    • 0.导语
      • 1.IF实现
        • 2.WHILE实现
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档