函数与默认参数
翻译整理自 cppreference - 函数。
1. 函数定义
int add(int a, int b) {
return a + b;
}声明与定义可分离:
// 声明(头文件)
int add(int a, int b);
// 定义(源文件)
int add(int a, int b) {
return a + b;
}2. 默认参数
void log(const std::string& msg, int level = 0);
log("info"); // 等价 log("info", 0)
log("err", 1);默认参数必须在最右的形参;声明时只能写一次。
3. inline
inline int square(int x) { return x * x; }inline 建议编译器内联展开;现代编译器也会自行决定。
4. constexpr
编译期可求值:
constexpr int fact(int n) {
return n <= 1 ? 1 : n * fact(n - 1);
}
constexpr int x = fact(5); // 120
5. 函数重载
同名不同签名:
int abs(int x) { return x < 0 ? -x : x; }
long abs(long x) { return x < 0 ? -x : x; }
double abs(double x) { return x < 0 ? -x : x; }6. 引用参数
void swap(int& a, int& b) {
int t = a; a = b; b = t;
}
int x = 1, y = 2;
swap(x, y);const 引用避免拷贝:
void print(const std::string& s) {
std::cout << s;
}7. 移动语义
void take(std::string&& s) {
std::string mine = std::move(s);
}
std::string s = "x";
take(std::move(s));8. 变长参数
C++11 起:可变参数模板:
template <typename... Args>
void print(Args... args) {
(std::cout << ... << args); // C++17 fold expression
}
print(1, " ", 2.0, "\n");<cstdarg> 提供 C 风格 va_list(保留,但不推荐)。
9. 函数指针与 lambda
int (*op)(int, int);
auto add = [](int a, int b) { return a + b; };
op = +add; // lambda 转函数指针
op(1, 2);
std::function<int(int, int)> f = add;lambda 形式
[capture](params) mutable -> return_type { body };
auto sq = [](int x) { return x * x; };
int base = 10;
auto add_base = [base](int x) { return x + base; }; // 按值捕获
auto inc = [&base]() { base++; }; // 引用捕获
auto all = [=]() { ... }; // 按值捕获所有
auto allr = [&]() { ... }; // 引用捕获所有
10. std::function 与 std::bind
#include <functional>
std::function<int(int)> f = [](int x) { return x * 2; };
auto bound = std::bind(f, std::placeholders::_1);
bound(5);11. 函数返回值优化
std::vector<int> makeVec() {
std::vector<int> v(1000);
return v; // RVO,不拷贝
}
auto v = makeVec();C++17 起保证复制消除。
小结
C++ 函数特性丰富:默认参数、重载、引用、移动、lambda、constexpr、模板,让函数式与命令式混合编程成为可能。