问题历史
C++从一开始就是作为一种支持函数重载的语言设计的——允许声明多个具有相同名称但不同参数的函数。这使得创建可读且方便的API成为可能。
问题
当具有相同名称的函数变多时,编译器需要根据参数的类型、转换、默认参数和引用来选择合适的实现。在粗心的重载中会出现歧义和难以捕捉的错误。
解决方案
编译器根据参数序列的最佳匹配、类型匹配的准确性和最小转换来选择函数。但需要注意细节:如果存在重要的转换或默认参数,可能会意外出现歧义。
代码示例:
void foo(int x); void foo(double x); void foo(int x, int y = 0); foo(5); // 调用void foo(int x),因为这是精准匹配 foo(5.2); // 调用void foo(double x) foo(5, 6); // 调用void foo(int x, int y)
关键特点:
可以仅按返回类型重载函数吗?
不可以。重载只能根据参数的类型和数量,返回类型不参与重载解析。
int foo(); double foo(); // 错误:不能仅按返回类型重载!
如果所有参数都可以转换,编译器如何选择重载函数?
编译器选择“最佳匹配”——需要最少的类型转换的函数,或者完全匹配。如果存在歧义,代码将无法编译。
void bar(int); void bar(long); bar(1); // int精准匹配:将调用bar(int)
可以将默认参数的重载与普通重载混合使用吗?
可以,但如果函数的签名重叠,可能会导致调用模糊。
void test(int x); void test(int x, int y = 10); test(5); // 错误:模糊 - 两者都适用
在库中发现有重载函数与重叠的默认参数,这导致在更新代码时出现编译错误。
优点:
缺点:
在项目中达成协议——不混合使用带有默认参数的重载,或仅使用一个带默认值的函数,或仅根据唯一参数进行重载。
优点:
缺点: