遍历对象 1 2 3 for (auto &a : A){ cout << a << endl; }
在 C++ 中, 这种范围 for 循环适用于符合以下条件的对象 A:
A 是一个标准容器或具有 begin() 和 end() 方法的对象 如果 A 是一个 STL 容器 (如 std::vector, std::list, std::map 等),或者是自定义类型但提供了 begin() 和 end() 方法,那么可以直接使用范围 for 循环:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <vector> #include <iostream> int main () { std::vector<int > A = {1 , 2 , 3 , 4 , 5 }; for (auto &a : A) { std::cout << a << " " ; } return 0 ; } # 等效于: for (auto it = A.begin (); it != A.end (); ++it) { auto &a = *it; }
A 是一个普通数组 C++11 开始,范围 for 也支持 C-style 数组 :
1 2 3 4 int A[] = {1 , 2 , 3 , 4 , 5 };for (auto &a : A) { std::cout << a << " " ; }
A 是一个自定义类,但必须实现 begin() 和 end() 如果 A 是一个 自定义类 ,必须提供 begin() 和 end() 方法,且返回的是可迭代对象(通常是迭代器):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> #include <vector> class MyClass { std::vector<int > data = {1 , 2 , 3 , 4 , 5 }; public : auto begin () { return data.begin (); } auto end () { return data.end (); } }; int main () { MyClass A; for (auto &a : A) { std::cout << a << " " ; } }
A 不是一个指针 如果 A 是一个指针,则不能直接用于 for(auto &a : A),因为指针本身并不是一个可迭代对象:
1 2 3 4 int * A = new int [5 ]{1 , 2 , 3 , 4 , 5 };
但可以这样遍历:
1 2 3 4 for (int i = 0 ; i < 5 ; ++i) { std::cout << A[i] << " " ; } delete [] A;
总结 可以使用 for(auto &a : A){} 的情况 : • A 是 STL 容器 (如 vector,list,map 等) • A 是 普通数组 • A 是 实现了 begin() 和 end() 的自定义类 不能直接使用的情况 : • A 是 指针 (但可以使用普通 for 循环) • A 没有 begin() 和 end() 方法(如 POD 结构体)
容器插入对象 顺序容器(如 vector
、deque
、list
) push_back(value)
:在容器尾部添加元素(适用于 vector
、deque
、list
)。push_front(value)
:在容器头部添加元素(适用于 deque
、list
)。insert(pos, value)
:在指定迭代器 pos
位置插入元素(适用于 vector
、deque
、list
)。emplace_back(value)
:在尾部原地构造元素,避免不必要的拷贝(适用于 vector
、deque
)。emplace(pos, value)
:在指定位置原地构造元素(适用于 vector
、deque
、list
)。关联容器(如 unordered_map
、unordered_set
、map
、set
) insert(value)
:插入元素,若键已存在(对于 map
和 set
),则不会覆盖原值。emplace(value)
:类似 insert()
,但直接在容器内部构造对象,避免额外拷贝。operator[]
(适用于 map
和 unordered_map
) :M[key] = value;
:如果 key
存在,则更新值;如果 key
不存在,则创建新键并赋值。M[key].push_back(value);
:适用于 unordered_map<int, vector<int>>
这种情况,直接向 vector
追加元素。适用于 unordered_map<int, vector<int>> M
的插入方法 情况 方法 适用场景 插入新的 key-value 对 M.insert({key, {value}});
key
不存在时插入直接赋值 M[key] = {value};
创建新 key
或覆盖旧值 向 vector
追加元素 M[key].push_back(value);
key
存在时向 vector
追加
容器中查找元素 顺序容器(如 vector
、deque
、list
) std::find
用于查找顺序容器中是否存在某个元素,返回一个迭代器:
如果找到元素,返回指向该元素的迭代器。 如果没有找到,返回 end()
迭代器。 1 2 3 4 5 6 7 8 9 10 #include <algorithm> #include <vector> std::vector<int > v = {1 , 2 , 3 , 4 , 5 }; auto it = std::find (v.begin (), v.end (), 3 );if (it != v.end ()) { std::cout << "Found: " << *it << std::endl; } else { std::cout << "Not Found" << std::endl; }
关联容器(如 set
、map
、unordered_map
、unordered_set
) find()
用于查找元素并返回指向该元素的迭代器。如果元素不存在,返回容器的 end()
迭代器在 unordered_map
或 unordered_set
中,find()
是基于哈希查找的,平均时间复杂度为 O(1)。 在 map
或 set
中,find()
是基于红黑树的,平均时间复杂度为 O(log n)。 1 2 3 4 5 6 7 8 9 #include <set> std::set<int > s = {1 , 2 , 3 , 4 , 5 }; auto it = s.find (3 );if (it != s.end ()) { std::cout << "Found: " << *it << std::endl; } else { std::cout << "Not Found" << std::endl; }
count()
用于检查容器中是否存在指定元素。它返回元素的个数(对于 set
和 unordered_set
,最大值是 1,因为元素唯一;对于 map
和 unordered_map
,返回的是键值对的个数):对于 unordered_map
和 unordered_set
,count()
的平均时间复杂度为 O(1)。 对于 map
和 set
,count()
的时间复杂度为 O(log n)。 1 2 3 std::map<int , std::string> m = {{1 , "one" }, {2 , "two" }}; std::cout << "Count of key 1: " << m.count (1 ) << std::endl; std::cout << "Count of key 3: " << m.count (3 ) << std::endl;
特定查找方法 operator[]
(map
和 unordered_map
) 用于通过键直接访问元素。如果键不存在,会插入一个默认构造的元素(map
和 unordered_map
特有):1 2 3 std::unordered_map<int , std::string> umap; umap[1 ] = "one" ; std::cout << "Value for key 1: " << umap[1 ] << std::endl;
注意,operator[]
不会告诉你元素是否存在,它直接返回对应的值。
Lambda 表达式 基本语法 1 [capture-list](parameters) -> return_type { body }
各部分解释:
capture-list :捕获外部变量的列表parameters :参数列表(可选)return_type :返回类型(可选,通常由编译器推导)body :函数体捕获列表的不同形式 1 2 3 4 5 6 7 8 [] [=] [&] [x, &y] [=, &x] [&, x] [this ] [*this ]
常见用法示例 简单的Lambda函数 1 2 auto add = [](int a, int b) { return a + b; };int sum = add (3 , 4 );
捕获外部变量 1 2 3 int multiplier = 10 ;auto multiply = [multiplier](int x) { return x * multiplier; };int result = multiply (5 );
修改捕获的值(使用mutable) 1 2 3 4 int counter = 0 ;auto increment = [counter]() mutable { return ++counter; };cout << increment (); cout << counter;
捕获引用 1 2 3 4 int counter = 0 ;auto increment = [&counter]() { return ++counter; };cout << increment (); cout << counter;
指定返回类型 1 auto divide = [](double a, double b) -> int { return a / b; };
进阶用法示例 Lambda作为函数参数 1 2 3 4 5 6 7 vector<int > nums = {1 , 2 , 3 , 4 , 5 }; sort (nums.begin (), nums.end (), [](int a, int b) { return a > b; });auto it = find_if (nums.begin (), nums.end (), [](int x) { return x > 3 ; });
泛型Lambda(C++14及以后) 1 2 3 4 auto add = [](auto a, auto b) { return a + b; };int sum1 = add (3 , 4 ); string sum2 = add (string ("Hello, " ), string ("World" ));
Lambda自引用(C++20及以后) 1 2 3 4 5 6 auto factorial = [](this auto && self, int n) -> int { if (n <= 1 ) return 1 ; return n * self (n - 1 ); }; int result = factorial (5 );
语法解释:
this auto&& self
:声明lambda自身的参数使用self
调用lambda本身,实现递归 Lambda模板(C++20) 1 2 3 4 auto print = []<typename T>(vector<T> const & v) { for (auto const & element : v) cout << element << ' ' ; };
Lambda与STL结合使用 1 2 3 4 5 6 7 8 vector<int > v = {1 , 2 , 3 , 4 , 5 }; transform (v.begin (), v.end (), v.begin (), [](int x) { return x * x; });int sum = accumulate (v.begin (), v.end (), 0 , [](int total, int current) { return total + current * 2 ; });
捕获初始化(C++14) 1 2 3 auto generator = [counter = 0 ]() mutable { return ++counter; };cout << generator (); cout << generator ();
总结 C++ Lambda表达式语法总结表 语法特性 示例 说明 基本语法 [](int x) { return x*x; }
最简单的lambda表达式定义 值捕获 [x](int y) { return x+y; }
以值方式捕获变量x 引用捕获 [&x](int y) { x += y; }
以引用方式捕获变量x 隐式值捕获 [=](int y) { return val+y; }
以值方式捕获所有使用的外部变量 隐式引用捕获 [&](int y) { val += y; }
以引用方式捕获所有使用的外部变量 混合捕获 [=, &x](int y) { x = val+y; }
默认值捕获,x以引用方式捕获 this捕获 [this](){ this->value++; }
捕获当前对象的this指针 mutable关键字 [x](int y) mutable { x++; }
允许修改值捕获的变量 返回类型 [](int x) -> double { return x/2.0; }
明确指定返回类型 泛型参数 [](auto x) { return x*x; }
使用auto实现泛型lambda 捕获初始化 [sum = 0](int x) mutable { return sum += x; }
在捕获列表中初始化变量 lambda模板 []<typename T>(T x) { return x; }
将lambda定义为模板 lambda自引用 [](this auto&& self, int n) { return n > 0 ? n * self(n-1) : 1; }
lambda递归调用自身 捕获*this [*this]() { value++; }
捕获当前对象的副本 捕获结构化绑定 auto [a, b] = p; [a, b]() { return a+b; }
捕获结构化绑定变量
常见应用场景 应用场景 示例 说明 STL算法 sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
自定义排序规则 条件筛选 auto it = find_if(v.begin(), v.end(), [](int x) { return x > 10; });
查找符合条件的元素 转换操作 transform(v1.begin(), v1.end(), v2.begin(), [](int x) { return x*x; });
将元素进行转换 事件处理 button.onClick([&](auto e) { handleClick(); });
UI事件回调 线程/异步 std::thread t([&]() { processData(); });
线程函数 递归算法 std::function<int(int)> fib = [&fib](int n) { return n <= 1 ? n : fib(n-1) + fib(n-2); };
使用std::function实现递归 IIFE [](){ setup(); return getValue(); }()
立即调用的lambda表达式
版权声明: 此文章版权归 AngFff 所有,如有转载,请注明来自原作者