Functions
函数是C++实体,它将一系列 语句 (即 函数体 )与一个 名称 及零个或多个 函数形参 列表相关联。
// 函数名:"isodd" // 参数列表包含一个参数,参数名为"n",类型为int // 返回类型为bool bool isodd(int n) { // 函数体开始 return n % 2; } // 函数体结束
当函数被调用时,例如在 函数调用表达式 中,形参会从实参(在调用处提供或使用 默认参数 )初始化,并执行函数体中的语句。如果 参数列表 以 ... 结尾,则可以为函数提供额外参数,这样的函数称为 可变参数函数 。
int main() { for (int arg : {-3, -2, -1, 0, 1, 2, 3}) std::cout << isodd(arg) << ' '; // isodd 被调用 7 次,每次 // n 都通过 arg 进行拷贝初始化 }
非限定 函数调用表达式中的函数名称会通过一组称为 “实参依赖查找”(ADL) 的额外规则进行查找。
|
函数可以是 协程 ,此时它可以暂停执行并在之后恢复。 |
(since C++20) |
函数声明 可以出现在任意作用域中,但 函数定义 只能出现在命名空间作用域中,或者对于 成员 函数和 友元 函数,可以出现在类作用域中。在类体内声明且没有友元说明符的函数是类成员函数。这类函数具有许多附加属性,详见 成员函数 说明。
函数不是对象:不存在函数数组,函数不能按值传递或从其他函数返回。允许函数指针和函数引用(除了 main函数 和 大多数标准库函数 (since C++20) ),并可在这些函数本身无法使用的场景中使用。因此我们称这些函数是“可寻址的”。
每个函数都具有一个类型,该类型由函数的返回类型、所有形参的类型(经过数组到指针和函数到指针转换后,参见
形参列表
)
、函数是否为
noexcept
(C++17 起)
,以及对于非静态成员函数的 cv 限定
和引用限定
(C++11 起)
组成。函数类型还具有
语言链接
。不存在 cv 限定的函数类型(不要与
cv 限定函数
的类型混淆,例如
int
f
(
)
const
;
,或返回
cv 限定类型
的函数,例如
std::
string
const
f
(
)
;
)。任何添加到函数类型别名上的 cv 限定符都会被忽略。
同一作用域中的多个函数可以具有相同的名称,只要它们的参数列表以及(对于非静态成员函数)cv /ref (since C++11) 限定符不同。这被称为 函数重载 。仅返回类型 和noexcept规范 (since C++17) 不同的函数声明不能重载。 重载函数的地址 确定方式有所不同。
|
C++ 通过 lambda 表达式 实现 匿名函数 。 |
(C++11 起) |
函数对象
除了函数左值,函数调用表达式还支持指向函数的指针,以及任何重载了函数调用运算符或可转换为函数指针的类类型值 (包括 lambda表达式 ) (C++11 起) 。这些类型统称为 FunctionObject s ,它们在 C++ 标准库中被广泛使用,例如可参见 BinaryPredicate 和 Compare 的用法。
标准库还提供了一系列预定义的 函数对象模板 以及组合新函数对象的方法(包括 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 起) )。