You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20函数重载优先级困惑:fct(f,i)调用为何无歧义?

C++20函数重载匹配疑问解析

示例代码

#include <iostream>
using namespace std;

void fct(int, float)  {cout << "Function no 1" << endl;}
void fct(int, double) {cout << "Function no 2" << endl;}
void fct(float&, int&)   {cout << "Function no 3" << endl;}
void fct(const float&, const int&)   {cout << "Function no 4" << endl;}

int main() {
    int       i = 1;
    int&     ri = i;
    char      c = 'A';
    float     f = 2.f;
    double    d = 3.0;
    const double& rdC = d;

    // 疑问调用A
    fct(f, 1);
    // 疑问调用B
    fct(f, i);
}

疑问点

  • 调用A:fct(f, 1);
    推理:第一个参数f可匹配函数3和4(完美类型匹配);第二个参数1可匹配函数1、2、4,其中函数4是完美匹配。判断调用函数4,实际结果符合预期。

  • 调用B:fct(f, i);
    推理:第一个参数f可匹配函数3和4(完美类型匹配);第二个参数i也可匹配函数3和4(完美类型匹配),因此判断调用存在歧义,但实际结果是匹配函数3,无法理解原因。若假设float&比const float&优先级更高,那调用A应该存在歧义,但实际并非如此。

解析

核心规则:重载决议的引用绑定优先级与参数匹配排序

C++重载决议中,当多个候选函数都能匹配调用时,会通过隐式转换序列的优劣筛选最优匹配,这里的关键是理解非const左值引用和const左值引用的绑定规则,以及参数匹配的整体比较逻辑。

调用A:fct(f, 1);

第二个参数1是右值(字面量),而函数3的第二个参数是int&——非const左值引用只能绑定到可修改的左值,无法绑定右值,因此函数3直接被排除出候选集。此时只有函数4能同时完美匹配两个参数:

  • f(float左值)可以绑定到const float&
  • 1(int右值)可以绑定到const int&
    函数1、2的第一个参数是int,f需要隐式转换为int,优先级低于完美匹配的函数4,所以最终调用函数4。

调用B:fct(f, i);

两个参数都是可修改的左值:

  • f(float左值)既可以绑定到float&(函数3),也可以绑定到const float&(函数4)
  • i(int左值)既可以绑定到int&(函数3),也可以绑定到const int&(函数4)

这里的关键规则是:对于左值参数,绑定到非const左值引用的优先级高于绑定到const左值引用。重载决议会比较所有参数的转换序列,当函数A的每个参数转换序列都不劣于函数B,且至少有一个参数的转换序列更优时,函数A会被选中。

函数3的两个参数绑定都是非const引用,比函数4的const引用绑定更优,因此函数3是更优匹配,不会出现歧义。

为什么调用A没有歧义?

调用A的第二个参数1是右值,无法绑定到函数3的int&参数,函数3直接被排除,自然不会和函数4产生竞争,因此不存在歧义。


内容的提问来源于stack exchange,提问作者TCH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:51:08