Wak*_*zil 4 c++ lambda functor c++11
这个例子(void function f(string& s1, string& s2)
)取自B.Stroustup新书"TCPL"第4版的第297/298页.
#include <iostream>
#include <functional>
#include <string>
#include <algorithm>
void f(std::string& s1, std::string& s2)
{
std::function<void(char* b, char* e)> rev =
[&](char* b, char* e) { if (1<e-b) { std::swap(*b,*--e); rev(++b,e); } };
rev(&s1[0],&s1[0]+s1.size());
rev(&s2[0],&s2[0]+s2.size());
}
int main()
{
std::string s1("Hello");
std::string s2("World");
f(s1, s2);
std::cout << s1 << " " << s2 << '\n';
}
Run Code Online (Sandbox Code Playgroud)
代码编译并打印出正确的结果,即函数f
反转输入字符串的字符.节目输出:
olleH dlroW
我可以理解下面表达式的语义.我的问题是接受它的语法,因为变量rev
是根据它自己定义的.
std::function<void(char* b, char* e)> rev =
[&](char* b, char* e) { if (1<e-b) { std::swap(*b,*--e); rev(++b,e); }
Run Code Online (Sandbox Code Playgroud)
(来自问题下的评论)
注意细微之处:在申报点的rev
是,语法,正好在发生声明符 rev
:
// vvv Point of declaration
std::function<void(char* b, char* e)> rev =
[&](char* b, char* e) { if (1<e-b) { std::swap(*b,*--e); rev(++b,e); }
Run Code Online (Sandbox Code Playgroud)
之后(包括等号和后面的所有内容),rev
现在表示具有已知类型(和大小)的有效对象,并且可以像范围中的任何其他已定义变量一样使用它.
另外,请考虑编译器如何构建此代码:
当它编译调用rev
(在函数定义内)时,这是:
...被调用的实际函数是无关紧要的,只要其签名和位置是已知的(后者的信息在声明时可供编译器使用).
当然,函数的其余部分也可以直接用于编译器构建.
因此,尽管"根据自身定义一个函数"看似奇怪,但它的工作原理很直接.