命名空间
变体
操作

函数

来自 cppreference.com
< cpp‎ | 语言
 
 
C++ 语言
 
 

C++ 中的函数将一系列的 语句 (函数体)与一个名称和零个或多个函数参数相关联。

// function name: "isodd"
// parameter list has one parameter, with name "n" and type int
// the return type is bool
bool isodd(int n)
{                 // the body of the function begins
    return n % 2;
}                 // the body of the function ends

当函数被调用时,例如在 函数调用表达式 中,参数将从参数(在调用时提供或 默认)中初始化,函数体中的语句将被执行。如果 参数列表... 结尾,则可以向函数提供额外的参数,这种函数称为 可变参数函数

int main()
{
    for (int arg : {-3, -2, -1, 0, 1, 2, 3})
        std::cout << isodd(arg) << ' '; // isodd called 7 times, each
                                        // time n is copy-initialized from arg
}

在函数调用表达式中,非限定 函数名将按照称为 "参数依赖查找" (ADL) 的额外规则集进行查找。

函数可以通过 返回 或通过 抛出 异常 来终止。

函数可以是 协程,在这种情况下,它可以挂起执行,以便稍后恢复。

(自 C++20 起)

函数声明 可以出现在任何作用域中,但 函数定义 只能出现在命名空间作用域中,对于 成员 函数和 友元 函数,则只能出现在类作用域中。在类体中声明而没有友元规范符的函数是类成员函数。此类函数具有许多附加属性,有关详细信息,请参阅 成员函数

函数不是对象:没有函数数组,函数不能按值传递或从其他函数中返回。指向函数的指针和引用(除了 主函数大多数标准库函数(自 C++20 起))是允许的,可以在无法使用函数本身的地方使用。因此,我们称这些函数是“可寻址的”。

每个函数都有一个类型,它包括函数的返回类型、所有参数的类型(在数组到指针和函数到指针转换之后,请参阅 参数列表) 、函数是否为 noexcept(自 C++17 起),以及对于非静态成员函数,cv-限定符 和 ref-限定符(自 C++11 起)。函数类型还有 语言链接。没有 cv-限定的函数类型(不要与 cv-限定函数 的类型混淆,例如 int f() const; 或返回 cv-限定类型 的函数,例如 std::string const f();)。如果将任何 cv-限定符添加到函数类型的别名,则该限定符将被忽略。

同一个作用域中的多个函数可以具有相同的名称,只要它们的 parameter lists 和非静态成员函数的 cv/ref(自 C++11 起)-限定符不同即可。这被称为 函数重载。仅在返回类型 和 noexcept 规范(自 C++17 起) 上不同的函数声明不能重载。重载函数的地址 的确定方式不同。

C++ 使用 lambda 表达式 实现 匿名函数

(自 C++11 起)

[编辑] 函数对象

除了函数左值,函数调用表达式还支持指向函数的指针,以及任何重载函数调用运算符或可转换为函数指针的类类型值(包括 lambda表达式(自 C++11 起)。这些类型统称为 函数对象,它们在整个 C++ 标准库中广泛使用,例如,二元谓词比较器 的用法。

标准库还提供了一些预定义的 函数对象模板 以及用于组合新的函数对象的方法(包括 std::less, std::mem_fn, std::bind, std::function(自 C++11 起), std::not_fn(自 C++17 起), std::bind_front(自 C++20 起), std::bind_back, std::move_only_function(自 C++23 起), std::copyable_function, 和 std::function_ref(自 C++26 起))。