博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++STL - 函数模板
阅读量:5037 次
发布时间:2019-06-12

本文共 4668 字,大约阅读时间需要 15 分钟。

模板主要是为了泛型编程,做到与类型无关
模板有函数模板和类模板,本文主要整理的是函数模板
1.函数模板定义
template<typename 类型形参1,typename 类型形参2,...>
返回类型 函数模板名(调用形参表){函数体}
在返回类型,调用形参表和函数体中,所需要类型的地方都可以引用模板形参表中类型形参
template
A function(B arg){ _C var; ...}
 
2.使用
函数模板名<类型形参1,类型形参2,...>(调用实参表)
即用<>中的替换template<>中的内容
eg:
int i = function<int,double,string>(1.23);
char c = function<char,string,Studnet>("hello");
 
3.类型参数
类型形参:前面必须带有typename或class关键字.
类型实参:传递给函数模板的类型实参既可以是基本类型(char/int/double等),也可以是类类型(Student/Teacher),甚至可以是其他模板实例化的类型(string),同时传递给函数模板的类型实参必须满足模板实现的具体要求, 否则将引发编译错误.
#include 
using namespace std;template
T add (T x, T y) { return x + y;}class Integer {public: Integer (int arg = 0) : m_var (arg) {} friend ostream& operator<< (ostream& os,Integer const& i) { return os << i.m_var; } Integer const operator+ (Integer const& rhs) const { return m_var + rhs.m_var; }private: int m_var;};int main (void) { cout << add
(123, 456) << endl; cout << add
(1.3, 4.6) << endl; cout << add
("Hello, ", "World !") << endl;// cout << add
("Hello, ","World !") << endl; cout << add
(123, 456) << endl; return 0;}
 
4.延迟编译
每个函数模板事实上都要被编译
两次:
(1)第一次是在编译器看到该函数模板被定义的时候,这时的编译器只对该函数模板做一般性的语法检查(
与类型无关),然后生成关于该函数模板的内部表示
(2)第二次是在编译器看到该函数模板被调用的时候,在用所提供的类型实参,结合之前生成的内部表示中的类型形参,做与类型相关的语法检查,并生成该函数模板的二进制指令代码.
 
5.隐式推断
(1)如果函数模板调用参数(园括号里的参数)的类型 相关与该模板的参数<尖括号里的参数>,那么在调用该函数模板的时候,即使不显示指定模板参数,编译器也有能力根据调用参数的类型隐式推断出正确的模板参数类型,这就叫模板参数的隐式推断.
(2)但是注意:如果编译器隐式推断的类型,和程序设计者所期望的类型不一致,有可能导致编译错误.
#include 
#include
using namespace std;template
void foo (T x, T y) { cout << "foo: " << typeid (x).name () << ' ' << typeid (y).name () << endl;}template
void bar (T const& x, T const& y) { cout << "bar: " << typeid (x).name () << ' ' << typeid (y).name () << endl;}template
R hum (T x) { R y; cout << "hum: " << typeid (x).name () << ' ' << typeid (y).name () << endl; return y;}void f1 (int x, int y) {}void f2 (double x, double y) {}int main (void) { int a, b; foo (a, b); // i i double c, d; bar (c, d); // d d char e[256], f[256]; foo (e, f); // Pc Pc bar (e, f); // A256_c A256_c // cout << sizeof (e) << endl; // 256// char (*p)[256] = &e;// e[0] = 'C'; // *(e+0) = 'C' foo ("hello", "tarena"); // PKc PKc// bar ("hello", "tarena"); // A6_c A7_c bar
("hello", "tarena"); // Ss Ss bar (string ("hello"), string ("tarena")); f1 (a, c); // c: double -> int f2 (a, c); // a: int -> double // int i = 1.2;// cout << i << endl; // 隐式推断的同时不能隐式转换// foo (a, c); // c: double -> int, T=int // a: int -> double, T=double foo ((double)a, c); // d d foo (a, (int)c); // i i foo
(a, c); // d d foo
(a, c); // i i// a = hum (c); // 返回值的类型不参与隐式推断 a = hum
(c); // d i return 0;}
 
6.重载
与普通函数一样,函数模板也可以形成重载关系,类型的约束性越强的版本越被有限选择
#include 
#include
#include
using namespace std;// 两个任意类型值的最大值template
T const& max (T const& x, T const& y) { cout << "<1" << typeid (x).name () << '>' << flush; return x < y ? y : x;}// 两个任意类型指针所指向目标的最大值template
T* const& max (T* const& x, T* const& y) { cout << "<2" << typeid (x).name () << '>' << flush; return *x < *y ? y : x;}// 两个字符指针所指向字符串的最大值char const* const& max (char const* const& x,char const* const& y) { cout << "<3" << typeid (x).name () << '>' << flush; return strcmp (x, y) < 0 ? y : x;}/*char const* max (char const* x,char const* y){ cout << "<3" << typeid (x).name () << '>' << flush; return strcmp (x, y) < 0 ? y : x;}*/// 三个任意类型值的最大值template
T const& max (T const& x, T const& y, T const& z) { cout << "<4" << typeid (x).name () << '>' << flush; return ::max (::max (x, y), z);}/*// 两个字符指针所指向字符串的最大值char const* const& max (char const* const& x,char const* const& y) { cout << "<3" << typeid (x).name () << '>' << flush; return strcmp (x, y) < 0 ? y : x;}*/int main (void) { int a = 123, b = 456; cout << ::max (a, b) << endl; cout << *::max (&a, &b) << endl; char const* c = "ab", *d = "abc"; cout << ::max (c, d) << endl; cout << ::max<> (c, d) << endl; cout << ::max
(c, d) << endl; char const* e = "abcd"; char const* const& f = ::max (c, d, e); cout << f << endl; char const* g = "12", *h = "123",*i = "1234"; ::max (g, h, i); cout << f << endl; return 0;}
 
 
暂时就是这些了...

转载于:https://www.cnblogs.com/niie9/p/6158723.html

你可能感兴趣的文章
用户体验之认知地图、思维导图和概念图
查看>>
bzoj3389 [Usaco2004 Dec]Cleaning Shifts安排值班
查看>>
bzoj3173 [Tjoi2013]最长上升子序列
查看>>
第八周作业
查看>>
spring事务隔离级别
查看>>
JavaEE:Eclipse开发工具的相关使用和XML技术
查看>>
LR_问题_如何将场景中的用户设置为百分比形式
查看>>
OpenShift-OKD3.10基础环境部署
查看>>
工程师淘金:开发Android主攻四大方向
查看>>
ASP.NET MVC——Controller的激活
查看>>
javascript中Array对象
查看>>
SQLSERVER中查看谁占用了Buffer Pool
查看>>
lamp环境安装shell脚本
查看>>
ASP.NET MVC使用jQuery实现Autocomplete
查看>>
model中字段格式验证
查看>>
host路径
查看>>
查看linux 内存
查看>>
HTTP 状态码
查看>>
Ubuntu 14.10 下卸载MySQL
查看>>
练习题 求字符串是否为回文
查看>>