C++20 type trait与变量模板 编译期求斐波那契数列

#include <iostream>
#include "common/log.h"
#include <limits>
#include <vector>
#include <span>
#include <array>
#include <type_traits>
using namespace AdsonLib;
//type traits可以在编译期判断一个类型T 是否为数值类型,是否是函数对象,是否是类,是否有构建函数,是不是指针,能否拷贝构造等

//变量模板

template<char c>
constexpr bool is_num_char_v = (c >= '0' && c <= '9');

//fib 使用变量模板
template<unsigned f> constexpr unsigned fib_num_v = fib_num_v<f-1> + fib_num_v<f-2>;
template<> constexpr unsigned fib_num_v<0> = 0;
template<> constexpr unsigned fib_num_v<1> = 1;

//fib 使用类模板
template<size_t n>
struct Fib {
    static constexpr size_t value = Fib<n-1>::value + Fib<n-2>::value;
};
template<>
struct Fib<0> {
    static constexpr size_t value = 0;
};
template<>
struct Fib<1> {
    static constexpr size_t value = 1;
};

template<size_t n>
struct Fib2 {
    enum{ value = Fib<n-1>::value + Fib<n-2>::value };
};
template<>
struct Fib2<0> {
    enum { value = 0 };
};
template<>
struct Fib2<1> {
    enum { value = 1 };
};

constexpr size_t FibFunc(size_t n) {
    if(n <= 0) return 0;
    if(n <= 2) return 1;
    return FibFunc(n-1) + FibFunc(n-2);
}

template<typename, typename ...>
void ShowTypeName() {
    LOG(INFO) << __PRETTY_FUNCTION__;
}

void SpanFunc(const std::span<int> &arr) {
    LOG(INFO) << "size: " << arr.size();
    for(auto && a : arr) {
        LOG(INFO) << a;
    }
}
int main(int argc, char *argv[]) {
    //约定俗成用::value取值
    static_assert(std::is_integral<int>::value);
    static_assert(!std::is_integral<float>::value);
    static_assert(std::is_floating_point<double>::value);
    static_assert(!std::is_same<int, double>::value);
    static_assert(std::is_class<struct Foo>::value);
    static_assert(std::is_pointer<int*>::value);
    //type  trait 
    LOG(INFO) << "int max: " << std::numeric_limits<int>::max();
    //变量模板
    //template<typename T> constexpr bool is_pointer_v = is_pointer<T>::value; 常用的在标准库里这么定义了
    static_assert(std::is_pointer_v<int*>);
    static_assert(is_num_char_v<'4'>);
    static_assert(!is_num_char_v<'x'>);
    //0 1 1 2 3 5 8 13 21 34
    LOG(INFO) << "fib num 20: " << fib_num_v<20> << " vs " << Fib<20>::value << " vs " << Fib2<20>::value << " vs " << FibFunc(20);

    //type trait之类型转换 添加cv限定,添加指针限定
    static_assert(std::is_same_v<std::remove_const_t<const int>, int>);
    static_assert(std::is_same_v<std::add_const<const int>::type, const int>);
    static_assert(std::is_same_v<std::add_pointer_t<const int>, const int *>);
    static_assert(std::is_same_v<std::remove_pointer_t<int *>, int>);
    ShowTypeName<std::remove_volatile_t<int * volatile>>();
    static_assert(std::is_same_v<std::add_volatile_t<int *>, int * volatile>);
    static_assert(std::is_same_v<std::remove_volatile_t<int * volatile>, int *>);
    //type trait decay 把变量传给函数参数时
    ShowTypeName<std::decay_t<int [5][5]>>();
    static_assert(std::is_same_v<std::decay_t<int [5][5]>, int (*)[5]>);
    static_assert(std::is_same_v<std::decay_t<int &>, int>);
    static_assert(std::is_same_v<std::decay_t<const int &>, int>);

    int a1[]{1,2,3};
    std::vector<int> a2{1,2,3};
    std::array a3{1, 2, 3};
    SpanFunc(a1);
    SpanFunc(a2);
    SpanFunc(a3);

    //类型和值绑定:编译时
    using Two = std::integral_constant<int,2>;
    using Four = std::integral_constant<int, 4>;
    static_assert(Two::value * Two::value == Four::value);
    static_assert(std::bool_constant<true>::value);
    static_assert(!std::bool_constant<false>::value);
    static_assert(std::true_type::value);
    static_assert(!std::false_type::value);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值