四、内联函数
4.1 inline关键字
cpp
#include <iostream>
using namespace std;
// inline建议编译器将函数代码插入调用处
// 适用于短小、频繁调用的函数
// 内联函数
inline int max(int a, int b) {
return (a > b) ? a : b;
}
// 类内部定义的函数默认为内联
class Point {
private:
int x, y;
public:
// 类内定义,默认为内联
Point(int x, int y) : x(x), y(y) {}
// 显式内联
inline int getX() const { return x; }
// 类外定义的内联函数
inline int getY() const;
};
int Point::getY() const {
return y;
}
// 内联函数通常放在头文件中
// inline.h
inline int square(int x) {
return x * x;
}
int main() {
cout << "max(10, 20) = " << max(10, 20) << endl;
cout << "square(5) = " << square(5) << endl;
Point p(3, 4);
cout << "Point: (" << p.getX() << ", " << p.getY() << ")" << endl;
return 0;
}
4.2 内联与宏
cpp
#include <iostream>
using namespace std;
// 宏定义(预处理阶段)
#define MAX_MACRO(a, b) ((a) > (b) ? (a) : (b))
#define SQUARE_MACRO(x) ((x) * (x))
// 内联函数(编译阶段)
inline int maxInline(int a, int b) {
return (a > b) ? a : b;
}
inline int squareInline(int x) {
return x * x;
}
int main() {
int a = 5, b = 10;
// 宏的问题:参数多次求值
int x = 5;
cout << "SQUARE_MACRO(x++): " << SQUARE_MACRO(x++) << endl; // x++执行两次
cout << "x = " << x << endl;
x = 5;
cout << "squareInline(x++): " << squareInline(x++) << endl; // x++执行一次
cout << "x = " << x << endl;
// 类型安全
cout << "maxInline(10, 20): " << maxInline(10, 20) << endl;
cout << "maxInline(3.14, 2.71): " << maxInline(3.14, 2.71) << endl;
return 0;
}
4.3 constexpr函数(C++11)
cpp
#include <iostream>
using namespace std;
// constexpr函数:可在编译期求值
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr int square(int x) {
return x * x;
}
// constexpr可用于模板
template<typename T>
constexpr T sum(T a, T b) {
return a + b;
}
// C++14中constexpr函数可以包含循环
constexpr int fibonacci(int n) {
if (n <= 1) return n;
int a = 0, b = 1;
for (int i = 2; i <= n; i++) {
int c = a + b;
a = b;
b = c;
}
return b;
}
int main() {
// 编译期计算
constexpr int fact5 = factorial(5);
constexpr int arrSize = square(10);
int arr[arrSize]; // 编译期常量数组大小
cout << "fact5 = " << fact5 << endl;
cout << "arrSize = " << arrSize << endl;
// 运行时计算
int n = 6;
int factN = factorial(n); // 运行时计算
cout << "fib(10) = " << fibonacci(10) << endl;
cout << "sum(3.14, 2.71) = " << sum(3.14, 2.71) << endl;
return 0;
}
五、函数模板
5.1 模板函数基础
cpp
#include <iostream>
#include <string>
using namespace std;
// 函数模板:泛型编程的基础
template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 多个模板参数
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
return a + b;
}
// C++14简化版
template<typename T, typename U>
auto multiply(T a, U b) {
return a * b;
}
// 模板特化
template<>
const char* max<const char*>(const char* a, const char* b) {
return (strcmp(a, b) > 0) ? a : b;
}
int main() {
// 隐式实例化
cout << "max(10, 20) = " << max(10, 20) << endl;
cout << "max(3.14, 2.71) = " << max(3.14, 2.71) << endl;
cout << "max('A', 'Z') = " << max('A', 'Z') << endl;
// 显式实例化
cout << "max<int>(10, 20) = " << max<int>(10, 20) << endl;
// 不同类型参数
cout << "add(10, 3.14) = " << add(10, 3.14) << endl;
cout << "multiply(5, 2.5) = " << multiply(5, 2.5) << endl;
// 字符串特化
cout << "max(\"apple\", \"banana\") = " << max("apple", "banana") << endl;
return 0;
}
5.2 模板参数推导
cpp
#include <iostream>
#include <vector>
using namespace std;
// 模板参数推导规则
template<typename T>
void func(T param) {
cout << "T: " << typeid(T).name() << endl;
}
template<typename T>
void funcRef(T& param) {
cout << "T&: " << typeid(T).name() << endl;
}
template<typename T>
void funcPtr(T* param) {
cout << "T*: " << typeid(T).name() << endl;
}
// 通用引用(转发引用)
template<typename T>
void funcForward(T&& param) {
cout << "T&&: " << typeid(T).name() << endl;
}
int main() {
int x = 10;
const int cx = 20;
int& rx = x;
func(x); // T = int
func(cx); // T = int (const被忽略)
func(rx); // T = int
funcRef(x); // T = int
funcRef(cx); // T = const int (const保留)
// funcRef(rx); // T = int
funcPtr(&x); // T = int
funcForward(x); // T = int&
funcForward(10); // T = int
return 0;
}
5.3 可变参数模板(C++11)
cpp
#include <iostream>
using namespace std;
// 递归终止函数
void print() {
cout << endl;
}
// 可变参数模板
template<typename T, typename... Args>
void print(T first, Args... args) {
cout << first << " ";
print(args...); // 递归调用
}
// 折叠表达式(C++17)
template<typename... Args>
auto sum(Args... args) {
return (args + ...); // 右折叠
}
template<typename... Args>
auto sum2(Args... args) {
return (... + args); // 左折叠
}
// 带初始值的折叠
template<typename... Args>
auto sumWithInit(Args... args) {
return (0 + ... + args); // 带初始值的右折叠
}
// 使用折叠表达式打印
template<typename... Args>
void printAll(Args... args) {
(cout << ... << args) << endl; // 折叠表达式
}
int main() {
print(1, 2, 3, 4, 5);
print("Hello", "World", 2024);
cout << "sum(1,2,3,4,5) = " << sum(1, 2, 3, 4, 5) << endl;
cout << "sumWithInit(1,2,3) = " << sumWithInit(1, 2, 3) << endl;
printAll("A", "B", "C", 123);
return 0;
}
六、Lambda表达式
6.1 Lambda基础
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Lambda表达式:匿名函数对象
int main() {
// 基本语法:[捕获列表](参数列表) -> 返回类型 { 函数体 }
// 1. 最简单的Lambda
[] { cout << "Hello Lambda!" << endl; }();
// 2. 带参数的Lambda
auto add = [](int a, int b) { return a + b; };
cout << "add(10, 20) = " << add(10, 20) << endl;
// 3. 指定返回类型
auto divide = [](double a, double b) -> double {
if (b == 0) return 0;
return a / b;
};
cout << "divide(10, 3) = " << divide(10, 3) << endl;
// 4. 捕获外部变量
int x = 10, y = 20;
// 值捕获
auto byValue = [=] { return x + y; };
cout << "byValue = " << byValue() << endl;
// 引用捕获
auto byRef = [&] { x = 100; y = 200; };
byRef();
cout << "x=" << x << ", y=" << y << endl;
// 混合捕获
int a = 1, b = 2, c = 3;
auto mixed = [=, &b] {
// a, c是值捕获,b是引用捕获
b = a + c;
return b;
};
cout << "mixed = " << mixed() << endl;
return 0;
}
6.2 捕获方式详解
cpp
#include <iostream>
#include <memory>
using namespace std;
class Widget {
public:
int value = 100;
void method() {
// 捕获this(C++11方式)
auto lambda1 = [this] {
cout << "value = " << value << endl;
};
lambda1();
// 捕获*this(C++17拷贝)
auto lambda2 = [*this] {
cout << "value = " << value << endl;
};
lambda2();
}
};
int main() {
// 捕获方式总结
int x = 10, y = 20, z = 30;
// [=] 值捕获所有
auto lambda1 = [=] { return x + y; };
// [&] 引用捕获所有
auto lambda2 = [&] { x = y = 100; };
// [=, &y] 值捕获除y外,y引用捕获
auto lambda3 = [=, &y] {
// x, z是值捕获,y是引用捕获
y = x + z;
};
// [&, y] 引用捕获除y外,y值捕获
auto lambda4 = [&, y] {
// x, z是引用捕获,y是值捕获
x = y + z;
};
// [this] 捕获this指针
Widget w;
w.method();
// 移动捕获(C++14)
unique_ptr<int> ptr = make_unique<int>(42);
auto lambda = [ptr = move(ptr)] {
cout << "value = " << *ptr << endl;
};
lambda();
return 0;
}
6.3 泛型Lambda(C++14)
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 泛型Lambda:参数使用auto
auto add = [](auto a, auto b) { return a + b; };
cout << "add(10, 20) = " << add(10, 20) << endl;
cout << "add(3.14, 2.71) = " << add(3.14, 2.71) << endl;
cout << "add(string, string) = " << add(string("Hello "), string("World")) << endl;
// 使用Lambda与STL
vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 过滤偶数
vector<int> evens;
copy_if(numbers.begin(), numbers.end(), back_inserter(evens),
[](auto n) { return n % 2 == 0; });
// 映射到平方
vector<int> squares;
transform(numbers.begin(), numbers.end(), back_inserter(squares),
[](auto n) { return n * n; });
// 累加
int sum = 0;
for_each(numbers.begin(), numbers.end(),
[&sum](auto n) { sum += n; });
// 使用constexpr Lambda(C++17)
constexpr auto square = [](int n) constexpr { return n * n; };
constexpr int result = square(5);
cout << "result = " << result << endl;
return 0;
}