C++:非类型模板参数的应用理解

556 阅读2分钟

模板参数可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参

类型形参:出现在模板参数列表中,跟在关键字 class 或 typename 之后定义,例如,class T 是名为 T 的类型形参,在这里 class 和 typename 没有区别。
非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

代码示例:

namespace bit
{
	// 定义一个模板类型的静态数组 
	template<class T, size_t N = 10> 
	class array
	{
    public:
        T& operator[](size_t index){
        	return _array[index];
        }
        const T& operator[](size_t index)const{
        	return _array[index];
        }
        size_t size()const{
        	return _size;
        }
        bool empty()const{
        	return 0 == _size;
        }
    private:
        T _array[N];
		size_t _size; 
	};
}

注意:

  1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
  2. 非类型的模板参数在编译期就能确认结果。

要点总结

模板在定义时候可以在尖括号里定义一个常量,作为参数。例如:template < class T, size_t N = 10 >。

1、常量的类型只能是:整形(及相关类型)、指针、引用。
2、传入的时候必须是const类型的数据。

通常用作给某个数组传长度。

模版习题

有如下类模板定义:

templatetypename T>
class BigNumber
    long n;
public:
    BigNumber(Ti):n(i)
    {}
    BigNumberoperator+(BigNumberb){
        returnBigNumber(n+b.n):
    }
};

已知b1、b2是BigNumber的两个对象,则下列表达式中错误的是( )。

A.b1+b2
B.b1+3
C.3+b1
D.3+3

标准答案:

C

答案解析:

C++运算符的重载有两个方式,一种是做为成员函数,另一种是做为友无函数。前种C++默认省略第一个参数(事实上是对象本身),而后一种是所有的参数都要写全。比如对加法的重载:成员方式为Coperator operator+(Coperator &op);,在调用的过程中我们可以理解为result=operator+(op);友元方式为friend COperator operator-(COperator &op1, COperator &op2);,在调用的过程中我们可以理解为result=operator-(op1, op2);

成员函数的话有个this指针,所以要想调用成员函数operator+ 的话前面的变量必须要是类对象

选项解析:

A.b1+b2 : 是BigNumber(b1)+BigNumber(b2)
B.b1+3 : 是BigNumber(b1)+BigNumber(3)
C.3+b1 : 整数3与b1相加时,3是int型,b1是BigNumber<T>型,int型不能和别的型做运算。常数3无法匹配到此模版中的+重载函数,编译器无法识别
D.3+3 : 就是正常的3+3


如有不同见解,欢迎留言讨论!!