模板编程基础 -(模板类型class和typename区别,模板模板参数)

一、class和typename区别

1. 大部分两者等价

2. 当需要显示指定类型时需要使用typename

template <class _Ty>
struct remove_cv<const _Ty> {
    using type = _Ty;

    /*template <template <class> class _Fn>
    using _Apply = const _Fn<_Ty>;*/
    template <template <class> class _Fn>
    using _Apply = const typename _Fn<_Ty>::type;
    //这里的typename不能改成class,因为编译器不知道type是啥,
    //他无法感知到是不是正确的,因此需要你显示指定typename,他是个类型
};

不指定他是个类型编译器无法感知就会报错。
在这里插入图片描述

using remove_cv_t = typename remove_cv<_Ty>::type;
//源码里几乎都是如此显示指示他是个类型

二、模板模板参数

模板的参数传入的是一个模板,这就是所谓的模板模板参数。其实stl里很多模板都是这样实现的。std::vector<std::vector>,这种例子很多,都是容器套容器的,怎么实现,就是通过模板模板参数去实现的。让一个参数去接受模板参数。使用格式template <class> class _Fn,需要指定接受什么样的模板参数,也就是能传入几个参数的模板template <class> class _Fn这个是1个参数``template <class t1, class t2> class _Fn接受两个参数的模板。。。,下边用于介绍的就是可以接受一个参数的。

template <class _Ty>
struct remove_cv {
	using type = _Ty;
	template <template <class> class _Fn>
	    using _Apply = _Fn<_Ty>;
}
//使用方法如下。stl里很多模板都是这样实现的
remove_cv<remove_cv<const int>::type>::_Apply<remove_cv>::type b = 10;
//这有点绕
//remove_cv<const int>::type,调用类型匹配去除掉const属性
//remove_cv<int>::_Apply<remove_cv>,调用_Apply后,传入一个参数的模板。
//remove_cv::type 获取到模板参数里的类型
//int b = 10;
//就是以上四步。

测试使用demo如下(这个是去除const和volatile的模板方法)

#include<iostream>
template <class _Ty>
struct remove_cv { // remove top-level const and volatile qualifiers
    using type = _Ty;

    template <template <class> class _Fn>
    using _Apply = _Fn<_Ty>; // apply cv-qualifiers from the class template argument to _Fn<_Ty>
};

template <class _Ty>
struct remove_cv<const _Ty> {
    using type = _Ty;

    template <template <class> class _Fn>
    using _Apply = const _Fn<_Ty>;
    /*template <template <class> class _Fn>
    using _Apply = const typename _Fn<_Ty>::type;*/
};

template <class _Ty>
struct remove_cv<volatile _Ty> {
    using type = _Ty;

    template <template <class> class _Fn>
    using _Apply = volatile _Fn<_Ty>;
};

template <class _Ty>
struct remove_cv<const volatile _Ty> {
    using type = _Ty;

    template <template <class> class _Fn>
    using _Apply = const volatile _Fn<_Ty>;
};

template <class _Ty>
using remove_cv_t = typename remove_cv<_Ty>::type;

template<class T>
struct MyStructs
{
    int a = 10;
};
int main(void)
{
    remove_cv_t<remove_cv<const int>::type> a = 10;
    remove_cv<remove_cv<const int>::type>::_Apply<remove_cv>::type b = 10;
    remove_cv<const int>::_Apply<MyStructs> type;
    //这个我在运行期间查看const属性被剥夺了
    //type.a = 10;
    //但是编译期间const属性在因此你没法去赋值。
    return 0;
}

结果如下:
在这里插入图片描述
在这里插入图片描述
结论就是这种用法编译期间会保持设置的属性(因此如果错误使用就会发生编译错误),但是运行期不会。

总结

学习了可变参数,模板类型区别,模板模板参数对理解模板编程又进了一步

参考

https://blog.csdn.net/janeqi1987/article/details/87342975
https://blog.csdn.net/qq_45801299/article/details/112298619

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值