说起函数重载,我不由得想起了C++的“多态”特性。多态又分为静态(编译时)多态和动态(运行时)多态,静态多态即为函数重载,动态多态则是虚函数机制。虚函数水较深,先不讨论,今天我们来看一下函数重载、作用以及要避免的一些坑(尤其是二义性错误)。

一、先来review一下 函数重载的概念

1. 函数名相同;

2. 形参类型和数量不同;

3. 不关返回值的事。

二、如何匹配要使用那个函数呢?

在C++ primary 中文5版 P217我们可以发现端倪。

1. 选定候选函数集 : ① 与被调用函数同名; ② 声明在调用点可见。=》没有,返回无匹配错误

2. 选定可行函数集:考察候选函数的参数列表,找出参数数量相同、且各个参数类型相同或者可以转换为形参的函数;=》没有,返回无匹配错误

3. 选出最佳匹配函数:层层选拔之后,如果幸存者函数有几个的话(不太可能),我们就要找出最最最合适的那一个,怎么找?实参和形参类型最接近的那一个。=》没有,返回无匹配错误

三、函数重载二义性

二义性是指在编译过程中无法找出最匹配的函数,或者说编译器在函数匹配过后还是有多个函数满足要求,无法确定该执行那一个引发的错误。

具体表现:

1. 参数数目引发的歧义

 int get(){
return 5;
}
int get(int a = ){
return a;
}
//调用get()
//不给参数和有默认参数会造成歧义。

2. 参数隐式转换引发的歧义

 int get(int m){
return m;
} long get(long m){
return m;
}
//double d = 1.234;
//调用get(d);double既可以隐式转换未long,也可以是int,或者说一般的数值类型之间都可以进行隐式类型转换,故无法确定那一个更加匹配。
 int get(int a){
return a;
}
int get(int &a){
return a;
}
//int m = 10;
//调用get(m)
//传值和传引用都可以完成调用,只不过值传递有拷贝的开销,而引用传递不会有。

3. 类型型相关歧义(较深内容,不容易理解)

P517-520,艰涩难懂,需要自己琢磨。

另外,我发现在P517的一个例子,是错误的,并未发生歧义,不会导致运行错误。

 #include <iostream>
#include <string>
using namespace std; struct B;
struct A {
A() = default;
A(const B&){
//转换B为A
cout << "A内部将B转换为A" << endl;
};
//...
string name = "A";
}; struct B {
B() = default;
operator A() const{
//类类型转换,B->A
cout << "B 类类型转换为 A" << endl;
};
//...
string name = "B";
}; A f(const A&) {
//...
} int main()
{
B b;
A a = f(b);
}

(由g++运行)

四、如何避免/解决

一是我们要注意默认参数,二是要考虑类型转换,使用explicit可以阻止隐式类型转换。


C++ 函数重载二义性的更多相关文章

  1. 函数重载二义性:error C2668: 'pow' : ambiguous call to overloaded function

    2013-07-08 14:42:45 当使用的函数时重载函数时,若编译器不能判断出是哪个函数,就会出现二义性,并给出报错信息. 问题描述: 在.cpp代码中用到pow函数,如下: long int ...

  2. C++函数重载,重写,重定义

    目录 1 重载 2 重写 3 重定义 4 函数重载二义性   笔者原创,转载请注明出处   C++中经常会提到重载,除了重载,还有重写,重定义,下面对这三个概念逐一进行区分 1 重载   函数重载是同 ...

  3. c++之函数重载(函数匹配)

    Case void f(); void f(int); void f(int, int); void f(double, double = 3.14); 匹配原则: 1)其形参数量与本次调用提供的实参 ...

  4. C++ 函数重载与函数匹配

    <C++ Primer>笔记,整理关于函数重载与函数匹配的笔记. 函数重载 void func(int a); //原函数 void func(double a); //正确:形参类型不同 ...

  5. 函数定义从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、new/delete 等

    今天一直在学习函数定义之类的问题,下午正好有机会和大家共享一下. 一.bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC+ ...

  6. const和非const函数重载

    成员函数后面加const,表示在该函数中不能对类的数据成员进行改变,比如下面的代码: #include <stdio.h> class A { private: mutable int a ...

  7. C++默认参数与函数重载 注意事项

    一.默认参数在C++中,可以为参数指定默认值.在函数调用时没有指定与形参相对应的实参时, 就自动使用默认参数. 默认参数的语法与使用:(1)在函数声明或定义时,直接对参数赋值.这就是默认参数:(2)在 ...

  8. 小猪猪C++笔记基础篇(六)参数传递、函数重载、函数指针、调试帮助

    小猪猪C++笔记基础篇(六) ————参数传递.函数重载.函数指针.调试帮助 关键词:参数传递.函数重载.函数指针.调试帮助 因为一些事情以及自己的懒惰,大概有一个星期没有继续读书了,已经不行了,赶紧 ...

  9. c++—— 函数重载(Overroad)

    5 函数重载(Overroad) 函数重载概念 1 函数重载概念 函数重载(Function Overload) 用同一个函数名定义不同的函数 当函数名和不同的参数搭配时函数的含义不同 2 函数重载的 ...

随机推荐

  1. Yarn概述——FAST, RELIABLE, AND SECURE DEPENDENCY MANAGEMENT

    官网链接:https://yarnpkg.com/lang/en/ 特性 Ultra Fast. Yarn caches every package it downloads so it never ...

  2. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_11-前端显示当前用户-前端请求jwt

    前端代码 sessionStorage也是key/value的格式 页头显示当前用户 查询jwt nginx里面的配置 测试 开启认证服务 进行登陆 跳转到首页就应该立即请求查询. 跳转到首页 coo ...

  3. java接口如何有效防止恶意请求

    java接口如何有效防止恶意请求?已解决   解决方法: 1.在redis数据库db0中新建一个名为rd_sms_request_count表,表结构: Ip:客户请求的ip Success_coun ...

  4. 一百四十三:CMS系统之评论布局和功能一

    模型 class CommentModel(db.Model): """ 评论 """ __tablename__ = 'comment' ...

  5. Github排名靠前的iOS库

    //iOS第三方开源库的吐槽和备忘 http://blog.ibireme.com/2013/09/23/ios-third-party-libs/#more-41361 //整理了一份Github上 ...

  6. (十四)用session和过滤器方法检验用户是否登录

    一.session方法 1.1 编写登录页面文件(index.html) <!doctype html> <html> <head> <title>测试 ...

  7. 返回日期格式:2017-12-03T13:58:58.901Z,判断时间间隔 如 “刚刚”,“一分钟前”,“一小时前”等

    后台返回的格式如下: 实现输出如下: 我的处理如下: // 处理数据 2017-11-28T02:41:09.487Z // 请求的时间戳.日期格式按照ISO8601标准表示,并需要使用UTC时间. ...

  8. HTML滚动时位置固定

    现在显示器一般都是宽屏,网页两端常常会留白. 两边可能会放一些推荐.标签或是导航什么的辅助模块. 现在有的网站页面内容过长时,用户将滚动条向下拉时,拉到一定程度,左右两侧的辅助模块就会固定在指定位置, ...

  9. localStorage 存储 数组

    let str = JSON.stringify(data.list); localStorage.setItem("options",str); let optionss=loc ...

  10. 为什么每次登录要手动 source /etc/profile ...

    由于执行顺序如下,故追个查看以下文件,看看是不是 JAVA_HOME, PATH 等环境变量在后面的文件中被重写覆盖了. 1. /etc/profile2. /etc/environment3. ~/ ...