C++实现模板中的非类型参数的方法
程序员文章站
2022-03-21 11:11:25
非类型模板参看,顾名思义,模板参数不限定于类型,普通值也可作为模板参数。在基于类型的模板中,模板实例化时所依赖的是某一类型的模板参数,你定义了一些模板参数(template
非类型模板参数的限制
非类型模板参看,顾名思义,模板参数不限定于类型,普通值也可作为模板参数。在基于类型的模板中,模板实例化时所依赖的是某一类型的模板参数,你定义了一些模板参数(template<typename t>)未加确定的代码,直到模板被实例化这些参数细节才真正被确定。而非类型模板参数,面对的未加确定的参数细节是指(value),而非类型。当要使用基于值的模板时,你必须显式地指定这些值,模板方可被实例化。
在函数模板中使用非类型参数
#include<iostream> using namespace std; //在函数模板中使用非类型参数 template<class t>void swap(t &a, t &b); template<typename t, unsigned n>void swap(t (&a)[n],t (&b)[n]); template<typename t, unsigned n>void printarray(t (&arr)[n]); int main(){ int m = 10, n = 90; swap(m,n); cout << "m = " << m << ", n = " << n << endl; int a[5] = { 1, 2, 3, 4, 5 }; int b[5] = { 10, 20, 30, 40, 50 }; swap(a, b); printarray(a); printarray(b); return 0; } template<class t> void swap(t &a,t &b){ t temp = a; a = b; b = temp; } template<class t, unsigned n> void swap(t (&a)[n],t (&b)[n]){ t temp; for (int i = 0; i < n;i++){ temp = a[i]; a[i] = b[i]; b[i] = temp; } } template<typename t, unsigned n>void printarray(t (&arr)[n]){ for (int i = 0; i < n;i++){ if (i == n-1){ cout << arr[i] << endl; } else{ cout << arr[i] << ", "; } } }
在类模板中使用非类型参数
#include<iostream> #include<cstring> #include<cstdlib> using namespace std; //动态数组实现,在类模板中使用非类型参数 template<typename t,int n> class array{ public: array(); ~array(); public: t & operator[](int i);//重载下标运算符 int length() const{ return m_length; }//获取数组长度 bool capacity(int n);//是否可改变数组容量 private: int m_length;//数组当前长度 int m_capacity;//当前内存容量 t *m_p;//指向数组内存的指针 }; template<typename t,int n> array<t, n>::array(){ m_p = new t[n]; m_capacity = m_length = n; } template<typename t,int n> array<t, n>::~array(){ delete[] m_p; } template<typename t,int n> t & array<t, n>::operator[](int i){ if (i<0||i>=m_length){ cout << "exception:array index out of bounds!" << endl; } return m_p[i]; } template<typename t,int n> bool array<t, n>:: capacity(int n){ if (n>0){ int len = m_length + n; if (len<=m_capacity){ m_length = len; return true; } else{ t *ptemp = new t[m_length + 2 * n*sizeof(t)]; if (null==ptemp){ cout << "exception: failed to allocate memory!"; return false; } else{ memcpy(ptemp,m_p,m_length*sizeof(t)); delete[] m_p; m_p = ptemp; m_capacity = m_length = len; } } } else{ int len = m_length - abs(n); if (len<0){ cout << "exception:array length is too small!" << endl; return false; } else{ m_length = len; return true; } } } int main(){ array<int, 5> arr; for (int i = 0, len = arr.length(); i < len;i++){ arr[i] = 2 * i; } cout << "first print:" << endl; for (int i = 0, len = arr.length(); i < len;i++){ cout << arr[i] << " "; } cout << endl; //扩大容量为增加的元素赋值 arr.capacity(8); for (int i = 5, len = arr.length(); i < len;i++){ arr[i] = 2 * i; } cout << endl; cout << "second print:" << endl; for (int i = 0, len = arr.length(); i < len;i++){ cout << arr[i] << " "; } cout << endl; arr.capacity(-4); cout << "third print: " << endl; for (int i = 0, len = arr.length(); i < len; i++){ cout << arr[i] << " "; } cout << endl; return 0; }
非类型模板参数的限制
非类型模板参数是有类型限制的。一般而言,它可以是常整数(包括enum枚举类型)或者指向外部链接对象的指针。
浮点数和类对象(class-type)不允许作为非类型模板参数:
template<double val> // error: 浮点数不可作为非类型模板参数 double process(double v) { return v * val; } template<std::string name> // error:类对象不能作为非类型模板参数 class myclass {} 稍作变通,我们即可使编译通过: template<double* pval> double process(const double& x) { return x * (*pval); } template<const char* name> class myclass { ... }
这样可顺利通过编译,但如果想在当前文件中使用这两个模板,还需要动一些手脚:
double val = 10; double res = process<&val>(20); // error: 表达式必须含有常量值 myclass<"hello"> x; // error: 模板参数不能引用非外部实体 const char* s = "hello"; myclass<s> x; // error: 表达式必须含有常量值
这里就点出另外一点注意事项,也就是非类型模板参数的限制,非类型模板参数可以是指针,但该指针必须指向外部链接对象,还记得在a.cpp中如何引用b.cpp中的全局变量吗,在a.hpp中使用extern关键字对外部变量加以引用。
// b.cpp double val = 3.14159265; char str[] = "hello";
// a.hpp extern double val; extern char str[];
// a.cpp #include "a.hpp" double res = process<&val>(10); myclass<str> x;
到此这篇关于c++实现模板中的非类型参数的方法的文章就介绍到这了,更多相关c++ 模板非类型参数内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
上一篇: 表单上传功能实现 ajax文件异步上传
推荐阅读
-
Python中实现字符串类型与字典类型相互转换的方法
-
Angularjs中$http以post请求通过消息体传递参数的实现方法
-
c++ 模板类,方法返回值类型是typedef出来的,或者是auto,那么此方法在类外面如何定义?
-
使ecshop模板中可引用常量的实现方法
-
在Layui 的表格模板中,实现layer父页面和子页面传值交互的方法
-
Java中成员变量与局部变量的区别、对象类型作为方法的参数和方法的返回值
-
模板字符串替换教程,实现一个 render(template, context) 方法,将 template 中的占位符用 context 填充
-
Java中构造方法、空指针异常现象、基本数据类型和引用数据类型作为参数传递的区别
-
SpringMVC处理参数中的枚举类型通用实现
-
在Python 3中实现类型检查器的简单方法