Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将此javascript代码重写为C++;11?_Javascript_C++_Lambda_C++11_Closures - Fatal编程技术网

如何将此javascript代码重写为C++;11?

如何将此javascript代码重写为C++;11?,javascript,c++,lambda,c++11,closures,Javascript,C++,Lambda,C++11,Closures,这是我在javascript权威指南中看到的javascript闭包代码。我想把它写成C++11 var uniqueID1 = (function() { var id = 0; return function() { return id++; }; })(); 这是我写的cpp代码。但它并没有被编译。C++11能否表示相同的表达式 auto c = []() -> int (*)() { int x = 0; return [&x]() -> i

这是我在javascript权威指南中看到的javascript闭包代码。我想把它写成C++11

var uniqueID1 = (function()
{
    var id = 0;
    return function() { return id++; };
})();    
这是我写的cpp代码。但它并没有被编译。C++11能否表示相同的表达式

auto c = []() -> int (*)() { int x = 0; return [&x]() -> int { return x++; }};
我正在使用VS2010

编辑: 这是我制作的完整javascript示例代码。您可以在web浏览器上轻松测试代码的工作方式

<head>
<script language="javascript">
var uniqueID1 = (function()
{
    var id = 0;
    return function() { return id++; };
})();

var uniqueID2 = (function()
{
      var id = 0;
      return function() { return id++; };
})();
</script>
</head>

<body>
        <input value = "uniqueid1" type="button" OnClick="alert(uniqueID1());"></input>
        <input value = "uniqueid2" type="button" OnClick="alert(uniqueID2());"></input>
</body>
</html>

var uniqueID1=(函数()
{
var-id=0;
返回函数(){return id++;};
})();
var uniqueID2=(函数()
{
var-id=0;
返回函数(){return id++;};
})();

好的,首先让我们分析一下JavaScript的功能

function()
{
    var id = 0;
    return function() { return id++; };
}
这将创建一个函数。一个没有名字的函数,它不接受任何参数。调用此函数时,将返回一个新函数。内部函数将访问一个局部作用域变量,该变量将是该内部函数状态的一部分

[]() -> std::function<int()>
{
  int x = 0;
  return [=]() mutable { return x++; };
}
每次调用此函数时,它都将返回一个新函数。这个新函数将有自己的状态(
varid=0;
毕竟必须做些什么)。外部函数的每次调用都将返回一个具有新状态的新函数

这:

将函数包装在一对括号中。这是运算符优先级规则所必需的,以允许此操作:

(function()
{
    var id = 0;
    return function() { return id++; };
})()
这将创建一个函数,然后调用该函数。这就是最后一个
()
在结尾所做的。它调用外部函数,外部函数创建具有自己作用域的内部函数并返回它

在此表达式中,外部函数丢失。它不见了;你不能再访问它了。您创建它的时间只够调用它,然后让它掉进垃圾收集的垃圾桶

鉴于所有这些,我们可以看到这一声明:

var uniqueID1 = (function()
{
    var id = 0;
    return function() { return id++; };
})();
创建外部函数,调用返回新函数的函数,然后将内部函数存储在名为
uniqueID1
的变量中

如果您需要证明这是正确的,请在HTML中尝试:

var uniqueMaker = function()
{
    var id = 0;
    return function() { return id++; };
};

var uniqueID1 = uniqueMaker();
var uniqueID2 = uniqueMaker();
您将得到与复制粘贴版本相同的答案

<>如果我们想用C++代码来模拟这个问题,我们需要用适当的C++代码执行每个步骤。 第一,内部功能。在C++中,词法范围不存在。因此,不能返回引用其他作用域中变量的函数。您只能返回一个lambda,该lambda包含来自另一个作用域的变量副本。此外,除非您明确允许,否则lambdas无法修改范围。因此,内部代码必须如下所示:

int id = 0;
return [=]() mutable { return ++id; };
这很好,但是现在我们需要创建一个lambda,它将返回这个有状态lambda函数。在C++中,具有状态的函数与函数指针不相同。由于lambda的类型是由编译器定义的,因此无法键入其名称。因此,我们必须使用
std::function
作为外部函数的返回类型

[]() -> std::function<int()>
{
  int x = 0;
  return [=]() mutable { return x++; };
}
[]()->std::function
{
int x=0;
return[=]()可变{return x++;};
}
这将创建一个lambda函数,当调用该函数时,该函数将返回一个具有自身状态的内部函数。独立于此函数的任何后续调用的状态。就像JavaScript示例一样

现在,这还不够。记住,JavaScript创建外部函数,调用它,并只存储其返回值。外部函数本身被丢弃。所以我们需要模仿这个。幸运的是,这在C++中是足够容易的;它看起来就像JavaScript:

([]() -> std::function<int()>
{
  int x = 0;
  return [=]() mutable { return x++; };
})()
([]()->std::function
{
int x=0;
return[=]()可变{return x++;};
})()
最后,我们将其固定在一个变量中:

auto uniqueID1 = ([]() -> std::function<int()>
{
  int x = 0;
  return [=]() mutable { return x++; };
})();
autouniqueid1=([]()->std::function
{
int x=0;
return[=]()可变{return x++;};
})();

uniqueID1
的类型将是
std::function
。它将不是外部函数的类型。外部函数只是用来创建内部范围的临时函数。

< P>我假定您不是要求逐字翻译,而是如何在C++中最好地表达这个构造。您的JavaScript构造在某种意义上是“伪造构造函数”,而您的ID生成器最好用C++中的简单类来表示。然后您只需创建该类的实例:

class UniqueID
{
    unsigned int value;
public:
    UniqueID() : value(0) { }
    unsigned int operator()() { return ++value; }
};
用法:

UniqueID gen1, gen2;

some_function(gen1());
another_function(gen2());
Foo x(Blue, "Jim", gen1());

这种方法比
std::function
包装器更轻,尽管直接向上的lambda将生成类似的数据结构(尽管您无法知道其类型名)。如果你希望第一个ID为0(虽然将0作为特殊值保留)可能是有用的,但是可以初始化<代码>值>代码> 1代码>代码>。C++:哇,这是我见过的C++中最不象C++的。我甚至不知道可以用任何C派生语言按值返回新创建的函数。编辑:正如Nicol Bolas提到的,你不能。仍然没有编译<代码>错误C3491:'x':无法在不可变的lambda中修改by值捕获我应该用gcc测试它吗?@Benjamin:然后使其可变,如编辑的版本所示;)@Benjamin well
0 0 0
是正确的响应,如果希望打印
0 1 2
,则应将
x
声明为static
static int x=0
或保存c()的结果,因为每次调用它时,
c()
实际上设置了
x=0
。@Benjamin:它当然返回
0
c()
返回一个存储状态的函数。每次调用
c()
都会返回一个不同的函数,该函数具有自己的独立状态。除非我看错了你的JavaScript代码,否则你的JavaScript代码也是这样做的。注意,JavaScript以调用外部函数的
()
结尾。因此,
uniqueID1
存储外部函数返回的函数。请参阅我的编辑细节。@本杰明:我已经完全重写了我的答案来解释JavaScript代码是如何工作的,以及如何在C++中复制它的效果。如果我正确理解JavaScript,那么每次调用JavaScript都应该