第6.5章: 默认实参

English

概述

C++ 允许函数形参带有默认值。 当调用者省略某个实参时,就使用该默认值。

在本章中,你将学到:

1. 基本默认实参

默认实参在参数列表中用 = value 指定。


void scale(int x, int factor = 2)
{
    ::fast_io::io::println(x * factor);
}

int main()
{
    scale(10);     // uses default factor = 2
    scale(10, 5);  // uses factor = 5
}

默认实参最适合配合内建类型使用,因为它们既廉价 又无歧义。

2. 默认实参应当放在声明中

默认实参应当出现在函数声明中, 而不是定义中。 这样可避免重复定义问题,并让头文件自给自足。


// header (math.hpp)
int power(int base, int exp = 2);

// source file (math.cpp)
int power(int base, int exp)
{
    int result{1};
    for(int i{}; i < exp; ++i)
        result *= base;
    return result;
}

如果你在两个地方都写默认值,编译器会拒绝这段代码。

3. 默认实参的顺序规则

一旦某个形参有了默认值,它右边的所有形参也必须 有默认值。


void f(int x = 0, int y = 0);   // ✔ OK
void g(int x = 0, int y);       // ❌ error — y has no default

这条规则确保调用不会产生歧义。

4. 与函数重载的交互

默认实参和重载可能以出人意料的方式相互作用。


void h(int x, int y = 0);
void h(int x);

像 h(5) 这样的调用会有歧义:

除非设计非常清晰,否则请避免混用重载与默认实参。

5. 默认实参何时求值

默认实参在调用点求值,而不是在 函数定义处。


int next_id()
{
    static int counter{};
    return ++counter;
}

void assign_id(int id = next_id());

int main()
{
    assign_id();  // id = 1
    assign_id();  // id = 2
}

每次调用都会重新对默认表达式求值。

要点