类模板、变量模板、别名模板 基础知识点一

缺省参数

一、 常规缺省参数:

  1. 类型模板参数缺省值得规定:如果某个模板参数有缺省值,那么从这个有缺省值的模板参数开始,后面的所有模板参数都得有缺省值。举例如下所示:当 T 给定缺省值int时,U没有给定缺省值就会报错。
  2. 偏特化版本中的类型模板参数不能够设置缺省值。
#include <iostream>
#include <list>
#include <map>
#include <string>

using namespace std;

namespace _nmsp1
{
    //TC的泛化版本
    //template <typename T=int,typename U> //error
    //template <typename T,typename U=int> //ok
    //template <typename T,typename U> //ok
    template <typename T=int,typename U=int> //ok
    struct TC
    {
        TC()
        {
            cout<<"TC泛化版本的构造函数"<<endl;
        }
        void functest1()
        {
            cout<<"functest1() 泛化版本"<<endl;
        }
    }; 
    //TC的特化版本
    //template <typename T=char> //error ,偏特化版本中的类型模板参数不能够设置缺省值
    template <typename T>
    struct TC<T,int>
    {

    };

    template <>   //TC的全特化版本
    struct TC<int,int>
    {

    };
}

int main()
{
	_nmsp1::TC<> mytc5; //使用了缺省模板参数,所以<>中啥也不用提供
    _nmsp1::TC<double> mytc6; //<>中第一个类型使用double, 第一个使用默认缺省参数

	return 0;
}

二、 后面的模板参数依赖前面的模板参数

#include <iostream>
#include <list>
#include <map>
#include <string>

using namespace std;

namespace _nmsp2
{
    template <typename T,typename U=T*>
    struct TC
    {
        TC()
        {
            cout<<"TC() 泛化版本"<<endl;
        }
        ~TC()
        {
            cout<<"~TC() 泛化版本"<<endl;
        }
    };
}

int main()
{
	_nmsp2::TC<double> mytc5;
    _nmsp2::TC<double,int> mytc6;

	return 0;
}

二、 在模板声明中指定缺省参数
不建议使用这种语法,看到了能够看懂。

#include <iostream>
#include <list>
#include <map>
#include <string>

using namespace std;

namespace _nmsp3
{
    //声明1,指定了 V 和 W
    template <typename T,typename U,typename V=int,typename W=char>
    struct TC; 

    //声明1,指定了 U
    template <typename T,typename U=char,typename V,typename W> // 这里为什么可以不指定 V 和 W 的缺省值,因为在声明1中已经指定了。如果声明1中没有指定的话,就会报错
    struct TC;

    //定义泛化版本的TC
    template <typename T,typename U,typename V,typename W>  //相当于 U,V,W 都有缺省值了
    struct TC
    {

    };
}

int main(int argc,char* argv[])
{
	_nmsp3::TC<int> mytc; //相当于 U,V,W 都有缺省值了,<>里面只提供了一个int

	return 0;
}

三、 类型别名

  1. 考虑到类型名比较长,所以一般用typedef(经典C++) 或者 using(C++11)给这些类型名起一个额外的别名来简化书写。

四、 非类型模板参数

  1. 数字是常量,类型一般为整形、指针类型。
#include <iostream>
#include <list>
#include <map>
#include <string>

using namespace std;

namespace _nmsp4
{
    //template<typename T,typename U,size_t arrsize=8> //这种写法和下面等价
    template<typename T,typename U,auto arrsize=8>
    struct TC
    {
        public:
            T m_arr[arrsize]; //编译的时候就确认数组的大小
            void functest2();
    };

    //template<typename T,typename U,size_t arrsize>  //注意这里实现的时候,arrsize 不能加缺省值
    template<typename T,typename U,auto arrsize>
    void TC<T,U,arrsize>::functest2()
    {
        cout<<"void TC<T,U>::functest2() 泛化版本"<<endl;
    }
}

int main(int argc,char* argv[])
{
	_nmsp4::TC<double,double> mytc; 
    for(size_t i=0;i<8;i++)
    {
        mytc.m_arr[i]=static_cast<double>(i);
    }

    for(size_t i=0;i<8;i++)
    {
        cout<<mytc.m_arr[i]<<endl;
    }

    _nmsp4::TC<double,double,18> mytc1; 
    mytc1.m_arr[17]=18.88;

    cout<<mytc1.m_arr[17]<<endl;

	return 0;
}
  1. 全局指针不能作为函数参数。但是全局数组是可以作为模板参数的。
#include <iostream>
#include <list>
#include <map>
#include <string>

using namespace std;

namespace _nmsp5
{
    template<const char* p>
    struct TC2
    {
    public:
        TC2()
        {
            printf("call TC2(): p=%s\n",p);
        }
    };

    const char* g_s="hello"; //全局指针
    const char g_s1[]="hello"; //全局数组
}

int main(int argc,char* argv[])
{
	//_nmsp5::TC2<_nmsp5::g_s> myct2; //compile error!
    _nmsp5::TC2<_nmsp5::g_s1> myct21;

	return 0;
}
  1. 字符串常量也无法作为模板参数。主要是因为:C++ 标准委员会有一些特殊的考虑,因为编译器可能会做优化,将相同的字符串链接到同一块地址空间上来。这个和不允许double,float等数组作为非类型模板参数是一样的原因。因为保存的是一个不精确的数字。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

repinkply

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值