第6.6章: 函数重载

English

概述

C++ 允许同名函数有多个,只要它们的参数列表不同。 这一特性称为函数重载。

在本章中,你将学到:

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) 这样的调用有歧义:

编译器无法偏向其中任何一个,因此该调用无法通过编译。

设计重载时,请确保调用不会以这种方式匹配多个重载。 很多情况下,你应当二选一:

要点