如何将C++闭包与变量参数同时重用——类似于JavaScript
How to re-use a C++ closure concurrently with variable arguments -- similar to JavaScript?
JavaScript创建了一个具有创建范围的闭包。例如:
function startGreeter( name, iterations, delay ) {
function greeter() {
console.log("greetings, "+name+"! i="+iterations);
if( --iterations )
setTimeout( greeter, delay );
}
setTimeout( greeter, delay );
}
startGreeter("Alex",3,1000);
startGreeter("Beth",2,1500);
JavaScript为greeter((函数创建了两个不同的闭包实例;一个给亚历克斯,一个给贝丝。当然,我们可以创建数十或数百个这样的实例;例如从数据数组中。
我想在C++中实现同样的功能;特别是能够创建一个函数的N个不同的同时闭包实例。
void startGreeterTask( AsyncManager& asyncManager, std::string name, int iterations, longtime msDelay )
{
TaskFunction greetingTask = [&]()
{
std::cout << "greetings, task " << name << "! iterations = " << iterations << std::endl;
if( --iterations )
{
asyncManager.setTimeout( greetingTask, msDelay );
}
};
asyncManager.setTimeout( greetingTask, msDelay );
}
int main( int argc, char* argv[] )
{
AsyncManager asyncManager;
startGreeterTask( asyncManager, "Alex", 3, 1000 );
startGreeterTask( asyncManager, "Beth", 2, 1500 );
asyncManager.execute();
}
AsyncManager提供了setTimeout((功能,如果我在main((的作用域中创建多个闭包,它就会工作。但是在startGreetingTask((中,闭包函数greetingTasks((的工作方式与JavaScript中的greeter((函数不同。据我所知,当startGreeterTask((完成执行时,greetingTask((和所有引用的参数都超出了范围,因此堆栈内存被释放。第二次调用startGreeterTask((会造成堆栈内存的混合使用,seg错误可以确保。
如何使startGreeterTask((像startGreeter((函数一样工作?
感谢Igor Tandetnik为我指明了正确的方向。我在这里发布了一个完整的答案,供其他人查找。
解决方案是(a(默认情况下使用复制捕获,(b(对我不想复制的类实例使用引用捕获,(c(添加mutable
关键字以允许修改捕获的变量,以及(d(避免闭包函数对其本身的引用。现在,闭包不是调用自己,而是调用定义闭包的函数。这种形式的自引用,通过一层间接,失去了JavaScript习惯用法的一点灵活性和表达能力,但它功能齐全,很好地解决了问题。
也就是说,如果其他人解决了这个特定的闭包自引用问题,我希望看到解决方案。
void greetTask( AsyncManager& asyncManager, std::string name, int iterations, longtime msDelay )
{
TaskFunction greetingClosure = [=,&asyncManager]() mutable
{
std::cout << "greetings, task " << name << "! iterations = " << iterations << std::endl;
if( --iterations )
{
greetTask( asyncManager, name, iterations, msDelay );
}
};
asyncManager.setTimeout( greetingClosure, msDelay );
}
- 类似于strcat()的函数出现问题
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 算术运算的结果类似于:C浮点变量中的1/3
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- 创建类似于布尔值的变量类型
- 如何在 Arduino 字符串的开头添加元素.类似于 JS unshift();
- Java 中是否有类似于 C++ 中引用类型"&"的内容?
- C++未知长度字符串的数组,其行为类似于 Python 字符串列表
- 如何创建类似于 QVariant 的变体类
- 对于多个字符(如 ETX/STX 对),是否有类似于 std::quote 的东西
- 初始化命名空间中的变量是否类似于将它们初始化为类成员?
- C++中用于结构的纯数组的类似于TableView/DataFrame的通用功能
- 有没有类似于stoi的函数可以用于模板类
- 如何编写一个类似于kernellist_head的c++风格的双链表实现
- 序列化模式类似于boost::序列化
- 构造一个类似于JSON文件c++的字符串
- 类似于javaScript的C 中的基于stackb的对象
- 是否有类似于CrossBridge的项目,但只是使用Javascript而不是Flash
- 类似于c++中的拼接,类似于Javascript中的拼接
- 在c++11中,类似于node.js/javascript回调的线程