| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C/C++普通函数与函数模板的区别,调用规则,模板局限性 -> 正文阅读 |
|
[C++知识库]C/C++普通函数与函数模板的区别,调用规则,模板局限性 |
普通函数与函数模板的区别 普通函数与函数模板区别:
示例: //普通函数 int myAdd01(int a, int b) { return a + b; } ? //函数模板 template<class T> T myAdd02(T a, T b) ? { return a + b; } ? //使用函数模板时,如果用自动类型推导,不会发生自动类型转换,即隐式类型转换 void test01() { int a = 10; int b = 20; char c = 'c'; cout << myAdd01(a, c) << endl; //正确,将char类型的'c'隐式转换为int类型 'c' 对应 ASCII码 99 ? //myAdd02(a, c); // 报错,使用自动类型推导时,不会发生隐式类型转换 ? myAdd02<int>(a, c); //正确,如果用显示指定类型,可以发生隐式类型转换 } ? int main() { ? test01(); ? system("pause"); ? return 0; } 总结:建议使用显示指定类型的方式,调用函数模板,因为可以自己确定通用类型T 普通函数与函数模板的调用规则 调用规则如下:
示例: //普通函数与函数模板调用规则 void myPrint(int a, int b) { cout << "调用的普通函数" << endl; } ? template<typename T> void myPrint(T a, T b) { cout << "调用的模板" << endl; } ? void test01() { //1、如果函数模板和普通函数都可以实现,优先调用普通函数 // 注意 如果告诉编译器 普通函数是有的,但只是声明没有实现,或者不在当前文件内实现,就会报错找不到 int a = 10; int b = 20; myPrint(a, b); //调用普通函数 ? ? ? ?//2、可以通过空模板参数列表来强制调用函数模板 myPrint<>(a, b); //调用函数模板 ? } ? int main() { ? test01(); ? system("pause"); ? return 0; } //普通函数与函数模板调用规则 void myPrint(int a, int b) { cout << "调用的普通函数" << endl; } ? template<typename T> void myPrint(T a, T b) { cout << "调用的模板" << endl; } ? template<typename T> void myPrint(T a, T b, T c) { cout << "调用重载的模板" << endl; } ? void test01() { //3、函数模板也可以发生重载 int c = 30; myPrint(a, b, c); //调用重载的函数模板 ? //4、 如果函数模板可以产生更好的匹配,优先调用函数模板 char c1 = 'a'; char c2 = 'b'; myPrint(c1, c2); //调用函数模板 } ? int main() { ? test01(); ? system("pause"); ? return 0; } 分析:如果函数模板可以产生更好的匹配,优先调用函数模板 以上面案例为例,编译器默认调用了普通函数,发现还需要把char转成int,又发现如果调用模板则只需确定类型即可,于是调用模板函数,最优选择。 总结:既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性 模板的局限性 局限性:
例如: template<class T> void f(T a, T b) { ? a = b; ? } 在上述代码中提供的赋值操作,如果传入的a和b是一个数组,就无法实现了 再例如: template<class T> void f(T a, T b) { ? if(a > b) { ... } ? } 在上述代码中,如果T的数据类型传入的是像Person这样的自定义数据类型,也无法正常运行 因此C++为了解决这种问题,提供模板的重载,可以为这些特定的类型提供具体化的模板 示例: #include<iostream> using namespace std; ? #include <string> ? class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } string m_Name; int m_Age; }; ? //普通函数模板 template<class T> bool myCompare(T& a, T& b) { if (a == b) { return true; } else { return false; } } //第一种方法:重载算术运算符==,缺点:太麻烦 ? //第二种方法: //具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型 //具体化优先于常规模板 template<> bool myCompare(Person &p1, Person &p2) { if ( p1.m_Name ?== p2.m_Name && p1.m_Age == p2.m_Age) { return true; } else { return false; } } ? void test01() { int a = 10; int b = 20; //内置数据类型可以直接使用通用的函数模板 bool ret = myCompare(a, b); if (ret) { cout << "a == b " << endl; } else { cout << "a != b " << endl; } } ? void test02() { Person p1("Tom", 10); Person p2("Tom", 10); //自定义数据类型,不会调用普通的函数模板 //可以创建具体化的Person数据类型的模板,用于特殊处理这个类型 bool ret = myCompare(p1, p2); if (ret) { cout << "p1 == p2 " << endl; } else { cout << "p1 != p2 " << endl; } } ? int main() { ? test01(); ? test02(); ? system("pause"); ? return 0; } 总结:
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:43:04- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |