函数重载的基本规则是:函数名必须相同,参数列表(类型、个数或顺序)必须不同;仅返回类型或仅参数名不同不构成重载;重载函数须在同一作用域内;const修饰符对非成员函数不参与重载区分。

函数重载的基本规则是什么
C++ 允许在同一作用域内声明多个同名函数,只要它们的参数列表(类型、数量或顺序)不同,编译器就能区分调用哪个版本——这就是函数重载。返回类型不同不能构成重载;仅 const 修饰符差异(如 void f(int) 和 void f(int) const)在非成员函数中也无效。
- 参数类型不同:比如
void print(int)和void print(double) - 参数个数不同:比如
void log(const char<em>)</em>和void log(const char, int) - 参数顺序不同:比如
void process(int, double)和process(double, int) - 引用/指针/const 限定带来的类型差异算作不同类型:比如
void f(int&)、f(const int&)、f(int)是三个合法重载
注意:默认参数不参与重载决议,它只是调用时的语法糖;如果两个重载函数因默认参数导致调用二义性(比如都可匹配 f()),编译会直接报错 error: call of overloaded 'f()' is ambiguous。
为什么 void f(int) 和 void f(unsigned int) 容易引发问题
这两个函数看似参数类型不同,但整型提升和隐式转换会让调用变得危险。比如传入字面量 5(类型是 int),两个函数都可匹配:一个精确匹配 int,另一个靠 int → unsigned int 转换。多数情况下编译器选前者;但若只有 unsigned int 版本存在,5 就会被转成无符号值——这本身没问题;但若传 -1,它会变成很大的正数(如 4294967295),逻辑就崩了。
- 避免对有符号/无符号整型做重载,尤其当涉及小整数字面量或负数输入时
- 更安全的做法是只提供一个接受
long long或std::int64_t的版本,或用模板 +std::enable_if约束 - 如果必须重载,加
= delete显式禁用危险转换:void f(unsigned int) = delete;
类内重载构造函数要注意什么
构造函数重载很常见,但容易忽略初始化列表和委托构造的交互。例如:
立即学习“C++免费学习笔记(深入)”;
class Vec {
public:
Vec() : Vec(0) {} // 委托给带参构造
Vec(int n) : size_(n), data_(new int[n]) {}
Vec(int n, int val) : Vec(n) { // 再次委托后,需手动赋初值
for (int i = 0; i < n; ++i) data_[i] = val;
}
private:
int size_;
int* data_;
};- 委托构造函数只能出现在初始化列表中,且不能与其它成员初始化共存(否则编译错误
error: constructor delegation cannot have member initializer list) - 所有重载构造函数都应保证资源安全:比如上面例子中,若
Vec(int, int)在new后抛异常,Vec(int)分配的内存就泄漏了——得用std::vector或智能指针替代裸指针 - 不要为同一个类写太多构造函数,考虑用工厂函数或
explicit防止意外隐式转换
模板函数和普通函数重载怎么共存
模板函数会参与重载决议,但普通函数优先级高于模板特化。比如:
void foo(int) { std::cout << "int\n"; }
template<typename T> void foo(T) { std::cout << "generic\n"; }
<p>foo(42); // 输出 "int",不是 "generic"
foo(3.14); // 输出 "generic",因为没匹配到非模板版- 这是好事:你总能用具体函数“覆盖”泛化行为
- 但要注意 SFINAE 失败不会报错,而是让该模板从重载集中移除;如果所有模板都 SFINAE 失败,又没有匹配的非模板函数,才报错
no matching function for call to 'foo' - 若想强制走模板,可用
foo<>(42)语法;若想禁用某类型,用delete:void foo(int) = delete;
重载解析发生在编译期,不看运行值;最常被忽略的是“用户定义转换函数 + 重载”组合,它可能触发多步隐式转换,导致意外匹配——遇到奇怪的调用失败或二义性,先检查有没有隐式转换路径。


















