woo*_*ngs 37 c++ lambda anonymous-class c++11
在Java中,当我需要一个回调函数时,我必须实现一个匿名类.在匿名类中,我可以访问外部变量final.
现在我在C++中做同样的事情.我理解C++ lambda工作得更好但有时候我需要传入许多带有匿名类的函数,我只需要传入一个实例.
我尝试了以下示例.它适用于GCC 4.3.4.
class IA {
public:
virtual int f(int x) = 0;
};
int main() {
class : public IA {
int f(int x) { return x + 1; }
} a;
doFancyWork(&a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有可能像这样捕获外部变量吗?
int main() {
int y = 100; // mark y as final if possible
class : public IA {
int f(int x) { return x + y; }
} a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
更新:
第二个例子不会编译.错误在这里,
prog.cpp: In member function ‘virtual int main()::<anonymous class>::f(int)’:
prog.cpp:9: error: use of ‘auto’ variable from containing function
prog.cpp:7: error: ‘int y’ declared here
prog.cpp: In function ‘int main()’:
prog.cpp:7: warning: unused variable ‘y’
Run Code Online (Sandbox Code Playgroud)
更新:
我刚刚意识到这样做的一些问题:
我想我必须离开匿名课程.
And*_*owl 37
无法自动捕获这些变量,但您可以使用其他方法.如果您想通过引用捕获:
int main() {
int y = 100; // mark y as final if possible
class IB : public IA {
public:
IB(int& y) : _y(y) {}
int f(int x) { return x + _y; }
private:
int& _y;
} a (y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果您想按值捕获,只需更改int&为int.
无论如何,你可以考虑使用lambdas元组作为"多回调"对象,如果这是困扰你的个别lambdas.您仍然可以将所有内容打包在一个对象中,并且可以免费进行捕获.
举个例子:
auto callbacks = make_tuple(
[] (int x) { cout << x << endl; },
[&] () { cout << y << endl; }, // y is captured by reference
[=] (int x) { cout << x + y << endl; }, // y is captured by value
// other lambdas here, if you want...
);
Run Code Online (Sandbox Code Playgroud)
您可以手动捕获变量(类似于lambda捕获在幕后执行的操作):
int main() {
int y = 100;
struct {
int& y;
int operator()(int x) { return x + y; }
} anon = { y };
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
#include <iostream>
...
std::cout << anon(10) << std::endl;
Run Code Online (Sandbox Code Playgroud)
按预期打印110.不幸的是,您不能使用此方法从另一个继承匿名类型,因为初始化列表可构造类型不能从其他类型继承.如果继承是至关重要的,那么你应该使用Andy Prowl概述的构造函数方法.
C++ lambda可以捕获"外部"变量.[编辑:当我第一次看到这个问题时,我不知何故错过了他提到他知道lambdas的地方.无论好坏,C++没有任何其他真正类似于匿名类的东西].
例如:
#include <iostream>
int main(){
int y = 100;
auto lambda = [=](int x) { return x + y; };
std::cout << lambda(2);
}
Run Code Online (Sandbox Code Playgroud)
...打印102作为输出.
请注意,尽管它看起来有点像函数,但C++ lambda确实会导致创建一个类.我想我应该补充一点:该类在技术上并不是匿名的,但它有一些从未直接可见的未指定名称.
编辑:我仍然有点不知道不使用lambdas的理由.是否意图使用包含许多成员函数的一个类?如果是这样,则不清楚您计划如何指定在哪个时间/为何目的调用哪个成员函数.我的直接反应是,这听起来很可疑,好像你试图扭曲语言来支持有问题的设计.
| 归档时间: |
|
| 查看次数: |
31649 次 |
| 最近记录: |