C++11中Lambda表达式的使用
Lambda表達式語法:[capture ] ( params ) mutable exception attribute -> return-type { body }
其中capture為定義外部變量是否可見(捕獲),若為空,則表示不捕獲所有外部變量,即所有外部變量均不可訪問,= 表示所有外部變量均以值的形式捕獲,在body中訪問外部變量時,訪問的是外部變量的一個副本,類似函數的值傳遞,因此在body中對外部變量的修改均不影響外部變量原來的值。& 表示以引用的形式捕獲,后面加上需要捕獲的變量名,沒有變量名,則表示以引用形式捕獲所有變量,類似函數的引用傳遞,body操作的是外部變量的引用,因此body中修改外部變量的值會影響原來的值。params就是函數的形參,和普通函數類似,不過若沒有形參,這個部分可以省略。mutalbe表示運行body修改通過拷貝捕獲的參數,exception聲明可能拋出的異常,attribute修飾符,return-type表示返回類型,如果能夠根據返回語句自動推導,則可以省略,body即函數體。除了capture和body是必需的,其他均可以省略。
Lambda表達式是用于創建匿名函數的。Lambda 表達式使用一對方括號作為開始的標識,類似于聲明一個函數,只不過這個函數沒有名字,也就是一個匿名函數。Lambda 表達式的返回值類型是語言自動推斷的。如果不想讓Lambda表達式自動推斷類型,或者是Lambda表達式的內容很復雜,不能自動推斷,則這時必須顯示指定Lambda表達式返回值類型,通過”->”。
引入Lambda表達式的前導符是一對方括號,稱為Lambda引入符(lambda-introducer):
(1)、[]??????? // 不捕獲任何外部變量
(2)、[=]????? ?//以值的形式捕獲所有外部變量
(3)、[&]????? ?//以引用形式捕獲所有外部變量
(4)、[x, &y] ???// x 以傳值形式捕獲,y 以引用形式捕獲
(5)、[=, &z]??? // z 以引用形式捕獲,其余變量以傳值形式捕獲
(6)、[&,x]? ???// x 以值的形式捕獲,其余變量以引用形式捕獲
(7)、對于[=]或[&]的形式,lambda 表達式可以直接使用 this 指針。但是,對于[]的形式,如果要使用 this 指針,必須顯式傳入,如:[this]() { this->someFunc(); }();
Lambda functions: Constructs a closure, an unnamed function object capable of capturing variables in scope.
In C++11, a lambda expression----often called a lambda----is a convenient way of defining an anonymous function object right at the location where it is invoked or passed as an argument to a function. Typically lambdas are used to encapsulate a few lines of code that are passed to algorithms or asynchronous methods.
A lambda function is a function that you can write inline in your source code (usually to pass in to another function, similar to the idea of a functor or function pointer). With lambda, creating quick functions has become much easier, and this means that not only can you start using lambda when you'd previously have needed to write a separate named function, but you can start writing more code that relies on the ability to create quick-and-easy functions.
下面是從其他文章中copy的測試代碼,詳細內容介紹可以參考對應的reference:
#include "Lambda.hpp"
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>///
// reference: http://en.cppreference.com/w/cpp/language/lambda
int test_lambda1()
{/*[] Capture nothing (or, a scorched earth strategy?)[&] Capture any referenced variable by reference[=] Capture any referenced variable by making a copy[=, &foo] Capture any referenced variable by making a copy, but capture variable foo by reference[bar] Capture bar by making a copy; don't copy anything else[this] Capture the this pointer of the enclosing class*/int a = 1, b = 1, c = 1;auto m1 = [a, &b, &c]() mutable {auto m2 = [a, b, &c]() mutable {std::cout << a << b << c << '\n';a = 4; b = 4; c = 4;};a = 3; b = 3; c = 3;m2();};a = 2; b = 2; c = 2;m1(); // calls m2() and prints 123std::cout << a << b << c << '\n'; // prints 234return 0;
}///
// reference: http://en.cppreference.com/w/cpp/language/lambda
int test_lambda2()
{std::vector<int> c = { 1, 2, 3, 4, 5, 6, 7 };int x = 5;c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; }), c.end());std::cout << "c: ";std::for_each(c.begin(), c.end(), [](int i){ std::cout << i << ' '; });std::cout << '\n';// the type of a closure cannot be named, but can be inferred with autoauto func1 = [](int i) { return i + 4; };std::cout << "func1: " << func1(6) << '\n';// like all callable objects, closures can be captured in std::function// (this may incur unnecessary overhead)std::function<int(int)> func2 = [](int i) { return i + 4; };std::cout << "func2: " << func2(6) << '\n';return 0;
}///
// reference: https://msdn.microsoft.com/zh-cn/library/dd293608.aspx
int test_lambda3()
{// The following example contains a lambda expression that explicitly captures the variable n by value// and implicitly captures the variable m by reference:int m = 0;int n = 0;[&, n](int a) mutable { m = ++n + a; }(4);// Because the variable n is captured by value, its value remains 0 after the call to the lambda expression.// The mutable specification allows n to be modified within the lambda.std::cout << m << std::endl << n << std::endl;return 0;
}//
// reference: https://msdn.microsoft.com/zh-cn/library/dd293608.aspx
template <typename C>
void print(const std::string& s, const C& c)
{std::cout << s;for (const auto& e : c) {std::cout << e << " ";}std::cout << std::endl;
}void fillVector(std::vector<int>& v)
{// A local static variable.static int nextValue = 1;// The lambda expression that appears in the following call to// the generate function modifies and uses the local static // variable nextValue.generate(v.begin(), v.end(), [] { return nextValue++; });//WARNING: this is not thread-safe and is shown for illustration only
}int test_lambda4()
{// The number of elements in the vector.const int elementCount = 9;// Create a vector object with each element set to 1.std::vector<int> v(elementCount, 1);// These variables hold the previous two elements of the vector.int x = 1;int y = 1;// Sets each element in the vector to the sum of the // previous two elements.generate_n(v.begin() + 2,elementCount - 2,[=]() mutable throw() -> int { // lambda is the 3rd parameter// Generate current value.int n = x + y;// Update previous two values.x = y;y = n;return n;});print("vector v after call to generate_n() with lambda: ", v);// Print the local variables x and y.// The values of x and y hold their initial values because // they are captured by value.std::cout << "x: " << x << " y: " << y << std::endl;// Fill the vector with a sequence of numbersfillVector(v);print("vector v after 1st call to fillVector(): ", v);// Fill the vector with the next sequence of numbersfillVector(v);print("vector v after 2nd call to fillVector(): ", v);return 0;
}/
// reference: http://blogorama.nerdworks.in/somenotesonc11lambdafunctions/template<typename T>
std::function<T()> makeAccumulator(T& val, T by) {return [=, &val]() {return (val += by);};
}int test_lambda5()
{int val = 10;auto add5 = makeAccumulator(val, 5);std::cout << add5() << std::endl;std::cout << add5() << std::endl;std::cout << add5() << std::endl;std::cout << std::endl;val = 100;auto add10 = makeAccumulator(val, 10);std::cout << add10() << std::endl;std::cout << add10() << std::endl;std::cout << add10() << std::endl;return 0;
}// reference: http://blogorama.nerdworks.in/somenotesonc11lambdafunctions/
class Foo_lambda {
public:Foo_lambda() {std::cout << "Foo_lambda::Foo_lambda()" << std::endl;}Foo_lambda(const Foo_lambda& f) {std::cout << "Foo_lambda::Foo_lambda(const Foo_lambda&)" << std::endl;}~Foo_lambda() {std::cout << "Foo_lambda~Foo_lambda()" << std::endl;}
};int test_lambda6()
{Foo_lambda f;auto fn = [f]() { std::cout << "lambda" << std::endl; };std::cout << "Quitting." << std::endl;return 0;
}
GitHub:https://github.com/fengbingchun/Messy_Test
總結
以上是生活随笔為你收集整理的C++11中Lambda表达式的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++11中std::bind的使用
- 下一篇: GDAL库简介以及在Windows下编译