• C++ 函数重载二义性


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

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

    1. 函数名相同;

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

    3. 不关返回值的事。

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

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

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

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

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

    三、函数重载二义性

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

    具体表现:

    1. 参数数目引发的歧义

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

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

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

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

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

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

     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 
     5 struct B;
     6 struct A {
     7     A() = default;
     8     A(const B&){
     9         //转换B为A
    10         cout << "A内部将B转换为A" << endl;
    11     };
    12     //...
    13     string name = "A";
    14 };
    15 
    16 struct B {
    17     B() = default;
    18     operator A() const{
    19         //类类型转换,B->A
    20         cout << "B 类类型转换为 A" << endl;
    21     };
    22     //...
    23     string name = "B";
    24 };
    25 
    26 A f(const A&) {
    27     //...
    28 }
    29 
    30 int main()
    31 {
    32     B b;
    33     A a = f(b);
    34 }

    (由g++运行)

    四、如何避免/解决

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


  • 相关阅读:
    Linear Predictors
    Non-Programmer's Tutorial for Python 3/File IO
    Python File I/O
    Introduction to Machine Learning
    Python3.6爬虫+Djiago2.0+Mysql --数据爬取
    MySql5.7 找回密码
    pyinstaller 打包python3.6文件成exe 运行
    python 连接mssql数据库
    Nopi 导出设置行高
    python登录aspx网站
  • 原文地址:https://www.cnblogs.com/yocichen/p/11152123.html
Copyright © 2020-2023  润新知