MxN*_*xNx 34 c++ lambda declaration definition c++11
在C++中,可以分离函数的声明和定义.例如,声明一个函数是很正常的:
int Foo(int x);
Run Code Online (Sandbox Code Playgroud)
在Foo.h贯彻它Foo.cpp.是否有可能与lambdas做类似的事情?例如,定义一个
std::function<int(int)> bar;
Run Code Online (Sandbox Code Playgroud)
在以下内容中bar.h实现它bar.cpp:
std::function<int(int)> bar = [](int n)
{
if (n >= 5)
return n;
return n*(n + 1);
};
Run Code Online (Sandbox Code Playgroud)
免责声明:我在C#中有使用lambdas的经验,但我没有在C++中使用过它们.
son*_*yao 40
你不能分开lambdas的声明和定义,也不能向前声明它.它的类型是一个未命名的闭包类型,它使用lambda表达式声明.但是你可以用std :: function对象来做到这一点,它被设计为能够存储任何可调用的目标,包括lambda表达式.
正如您所使用的示例代码所示std::function,请注意,对于这种情况bar确实是一个全局变量,并且您需要extern在头文件中使用它来使其成为声明(而不是定义).
// bar.h
extern std::function<int(int)> bar; // declaration
Run Code Online (Sandbox Code Playgroud)
和
// bar.cpp
std::function<int(int)> bar = [](int n) // definition
{
if (n >= 5) return n;
return n*(n + 1);
};
Run Code Online (Sandbox Code Playgroud)
再次注意,这不是lambda的单独声明和定义; 它只是单独声明和定义bar带有类型的全局变量std::function<int(int)>,它是从lambda表达式初始化的.
前向声明不是正确的术语,因为C++中的lambda是对象,而不是函数.代码:
std::function<int(int)> bar;
Run Code Online (Sandbox Code Playgroud)
声明一个变量,你不必强制分配它(该类型的默认值为"指向无函数的指针").你甚至可以编译它的调用...例如代码:
#include <functional>
#include <iostream>
int main(int argc, const char *argv[]) {
std::function<int(int)> bar;
std::cout << bar(21) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将干净地编译(但当然会在运行时疯狂地表现).
也就是说,您可以将lambda分配给兼容std::function变量并添加例如:
bar = [](int x){ return x*2; };
Run Code Online (Sandbox Code Playgroud)
在调用之前将导致编译良好的程序并生成输出42.
关于C++中lambda的一些非显而易见的事情(如果你知道其他有这个概念的语言)是那个
[..](...){...}即使签名完全相同,每个lambda 也有不同的不兼容类型.例如,你不能声明lambda类型的参数,因为唯一的方法是使用类似的东西,decltype([] ...)但是没有办法调用函数,因为[]...调用站点上的任何其他形式都是不兼容的.std::function如果你必须传递lambdas或将它们存储在你必须使用的容器中,这就解决了std::function.
Lambda可以按值捕获本地(但它们const除非你声明lambda mutable)或通过引用(但保证引用对象的生命周期不会短于lambda的生命周期由程序员决定).C++没有垃圾收集器,这是正确解决"向上funarg"问题所需的东西(你可以通过捕获智能指针来解决,但你必须注意引用循环以避免泄漏).
与其他语言不同,lambdas可以被复制,当你复制它们时,你正在拍摄它们内部捕获的按值变量的快照.对于可变状态,这可能是非常令人惊讶的,这是我认为const默认情况下捕获的值 - 值的原因.
合理化和记住lambdas的许多细节的方法是代码:
std::function<int(int)> timesK(int k) {
return [k](int x){ return x*k; };
}
Run Code Online (Sandbox Code Playgroud)
基本上就像
std::function<int(int)> timesK(int k) {
struct __Lambda6502 {
int k;
__Lambda6502(int k) : k(k) {}
int operator()(int x) {
return x * k;
}
};
return __Lambda6502(k);
}
Run Code Online (Sandbox Code Playgroud)
有一个微妙的区别,甚至可以复制lambda捕获引用(通常包含引用的类作为成员不能).
| 归档时间: |
|
| 查看次数: |
4813 次 |
| 最近记录: |