第6.6章: 函数重载
概述
C++ 允许同名函数有多个,只要它们的参数列表不同。 这一特性称为函数重载。
在本章中,你将学到:
- 什么是函数重载
- 重载决议如何工作
- 什么算作不同的参数列表
- 为什么仅凭返回类型无法重载函数
- 引用与
const如何影响重载选择 - 有歧义的重载如何产生
- 重载如何与默认实参交互
1. 基本的函数重载
两个或多个函数只要形参类型不同,就可以同名。
void print(int x)
{
::fast_io::io::println("int: ", x);
}
void print(double d)
{
::fast_io::io::println("double: ", d);
}
int main()
{
print(42); // calls print(int)
print(3.14); // calls print(double)
}
编译器根据实参类型选择正确的函数。
2. 什么算作不同的参数列表?
重载必须在形参类型或形参个数上有所不同。
void f(int);
void f(double); // OK — different type
void f(int, int); // OK — different number of parameters
这些全都是合法的重载。
3. 返回类型不参与重载
只有参数列表决定两个函数是否为不同的重载。 在重载决议中,返回类型被完全忽略。
int g();
double g(); // ❌ error — return type alone does not create a new overload
编译器必须在知道返回类型之前就选定重载。
auto x = g(); // which g() should this call?
由于返回类型无法消除调用的歧义,这组重载是非法的。 只有形参可以不同。
4. 用引用与 const 重载
引用与 const 限定符会影响重载决议。
void h(int & x)
{
::fast_io::io::print("non-const reference\n");
}
void h(int const & x)
{
::fast_io::io::print("const reference\n");
}
用 const 值调用 h 会选中 const 重载:
int main()
{
int a{10};
int const b{20};
h(a); // calls h(int &)
h(b); // calls h(int const &)
}
5. 有歧义的调用
有时编译器无法判断哪个重载更好。
void k(long);
void k(double);
int main()
{
k(0); // ❌ ambiguous — 0 can convert to long or double
}
当两个重载同样合适时,调用就有歧义。
6. 与默认实参结合的重载
默认实参与重载可能相互作用,有时会造成歧义。
void m(int x, int y = 0);
void m(int x);
像 m(5) 这样的调用有歧义:
- 第二个重载作为
m(int)直接匹配 - 第一个重载用
y的默认值也能作为m(int, int)匹配
编译器无法偏向其中任何一个,因此该调用无法通过编译。
设计重载时,请确保调用不会以这种方式匹配多个重载。 很多情况下,你应当二选一:
- 使用带默认实参的单个函数,或者
- 使用一组清晰的重载,且在重叠的签名上不带默认值
要点
- 函数重载允许同名函数有多个。
- 重载必须在形参类型或形参个数上不同。
- 仅凭返回类型无法重载函数。
const与引用会影响重载决议。- 有歧义的调用会导致编译错误。
- 如果签名重叠,默认实参可能让重载产生歧义。