所以説C/C++11的匿名函數(Lambda表達式)的方括號是什麽鬼啊...

Intro

今天晚上和同學聊天提到了C/C++11,然後注意到了其中的特性之一——也就是匿名函數,亦即Lambda表達式。

所謂匿名函數,最大的特點之一就是這樣的函數可以有名字也可以沒有名字,但它不需要命名就可以定義與使用,這就連帶地使之具有了臨時性

但是關於C/C++11的匿名函數(Lambda表達式),我有些東西真的想不通…

下面會以

爲例來定義相關函數,以闡述我關於這些匿名函數(Lambda表達式)的觀點。

Node.JS

我們先來看Node.JS當中的普通函數定義

Ordinary Function Definition
1
2
3
function psi(x) {
return 128 * x * x + 39;
}

與匿名函數(Lambda表達式)定義

Function Definition using Lambda Expression
1
2
3
var psi = (function (x) {
return 128 * x * x + 39;
});

匿名函數(Lambda表達式)調用起來可以像普通函數一樣

psi(1.)

如若不想讓這個函數占用一個單獨的名字,那麽可以在定義后立即調用,不過調用后亦會即刻銷毀

Anonymously Defining & Calling
1
2
3
(function (x) {
return 128 * x * x + 39;
})(1.);

就算是嵌套、複雜的函數亦可以如此這般進行定義

Complicated Lambda Expressions
1
2
3
4
5
6
7
8
9
10
11
12
(() => {
const http = require("http");
const hostname = "127.0.0.1";
const port = 3939;
http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
res.end("Hello World");
}).listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
})();

你甚至還可以把 (function (vars&params) {...}) 簡寫為 ((vars&params) => {...})

Simplified Lambda Expressions
1
2
3
4
5
6
var psi = ((x) => {
return 128 * x * x + 39;
});
((x) => {
return 128 * x * x + 39;
})(1.);

這是Node.JS的匿名函數(Lambda表達式),可以説是最靈活的一種。

Python

Python中的匿名函數真的是用lambda關鍵字來進行定義的,例如普通地定義函數

Lambda Expressions in Python(3.x)
1
2
3
4
def psi(x, y):
return 128 * x * y + 39
# <=>
psi = lambda x, y : 128 * x * y + 39

可以用下方的lambda表達式來替代,但是Pythonlambda表達式不能表示複雜的函數過程,僅僅適用於一個表達式出返回值的那種。

C/C++

到你C/C++的匿名函數(Lambda表達式)就神奇了…

Lambda Expressions in C/C++11
1
2
3
4
5
([] (x) { return 128 * x * x + 39; })(1.);
([=] (x) { return 128 * x * x + 39; })(1.);
([&] (x) { return 128 * x * x + 39; })(1.);
([&] (x, y) { return 128 * x * y + 39; })(1.);
([&y] (x) { return 128 * x * y + 39; })(1.);

看網上有這些用法…嗯?什麽意思??

我去網上在一個叫做C++11 FAQ中文版章節Lambda表達式中找到了相關的解釋

[&]是一個捕捉列表(capture list),用於描述將要被lambda函數以引用傳參方式使用的局部變量。如果我們僅想“捕捉”參數v,則可以寫為:[&v]。而如果我們想以傳值方式使用參數v,則可以寫為:[=v]。如果什麼都不捕捉,則為:[]。將所有的變量以引用傳遞方式使用時採用[&],而相對地,使用[=]則相應地表示以傳值方式使用所有變量。(譯註:“所有變量”即指lambda表達式在被調用處,所能見到的所有局部變量)

Extra!! about C/C++11 Standard

我所見過的很多同學,使用的C/C++開發環境是一款稱爲Dev-C++的老古董,裏面用的是gcc/g++ 4.9.2,去網上查了查,支持的編譯標準似乎只到C/C++98

其實除了用不了auto之外也沒什麽,雖説現在的gcc/g++都已經更新到第九代了…支持的標準也是2017年的C/C++17了…

References

  1. zhzz2012 - cpp11新特性講解與應用 https://blog.csdn.net/zhzz2012/article/details/52151660/
  2. C++11 FAQ中文版 Lambda表達式 https://wizardforcel.gitbooks.io/cpp-11-faq/content/18.html
  3. https://isocpp.org/wiki/faq/cpp11/