简体   繁体   English

如何将这个javascript代码重写为C ++ 11?

[英]How can I rewrite this javascript code to C++11?

This is the javascript closure code I saw at Javascript Definitive Guide. 这是我在Javascript权威指南中看到的javascript闭包代码。 I'd like to write it as C++11 我想把它写成C ++ 11

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

This is the cpp code I wrote. 这是我写的cpp代码。 But it isn't be compiled. 但它没有被编译。 Can C++11 represent the same expression? C ++ 11可以表示相同的表达式吗?

auto c = []() -> int (*)() { int x = 0; return [&x]() -> int { return x++; }};

I'm using VS2010 我正在使用VS2010

Edit: This is the full javascript sample code I made. 编辑:这是我制作的完整javascript示例代码。 You can test easily how the code works at your web browser. 您可以轻松测试代码在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>

OK, first let's break down what your JavaScript does. 好的,首先让我们分解你的JavaScript。

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

This creates a function. 这创建了一个功能。 A function with no name, which takes no parameters. 没有名称的函数,不带参数。 This function, when called, will return a new function. 调用此函数时,将返回一个新函数。 The inner function will have access to a locally scoped variable, and this variable will be part of the state of that inner function. 内部函数可以访问本地范围的变量,该变量将成为该内部函数状态的一部分。

Each time this function is called, it will return a new function. 每次调用此函数时,它都将返回一个函数。 That new function will have its own state ( var id = 0; has to do something, after all). 那个新函数将有自己的状态( var id = 0;毕竟必须做一些事情)。 Each call of the outer function will return a new function with new state. 外部函数的每次调用都将返回一个具有新状态的新函数。

This: 这个:

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

Wraps the function in a pair of parenthesis. 将函数包含在一对括号中。 This is needed for operator precedence rules, to allow this to work: 这是运算符优先级规则所必需的,以允许它工作:

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

This creates a function, and then calls the function. 这将创建一个函数,然后调用该函数。 That's what the last () do at the end. 这就是最后()最后做的事情。 It calls the outer function, which creates an inner function with its own scope and returns it. 它调用外部函数,它创建一个具有自己范围的内部函数并返回它。

In this expression, the outer function is lost . 在此表达式中,外部函数丢失 It's gone; 它消失了; you can't access it anymore. 你不能再访问它了。 You created it for just long enough to call it, then let it drop into the trashcan of garbage collection. 你创建它的时间足够长,可以调用它,然后让它进入垃圾收集的垃圾桶。

Given all of this, we can see that this statement: 鉴于所有这些,我们可以看到这句话:

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

Creates the outer function, calls the function which returns a new function, and then stores the inner function in a variable called uniqueID1 . 创建外部函数,调用返回新函数的函数,然后将内部函数存储在名为uniqueID1的变量中。

If you need proof that this is true, try this in your HTML: 如果您需要证明这是真的,请在HTML中尝试:

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

var uniqueID1 = uniqueMaker();
var uniqueID2 = uniqueMaker();

You'll get the same answer as your copy-and-paste version. 您将获得与复制粘贴版本相同的答案。

If we want C++ code to mimic this, we need to perform each step with proper C++ code. 如果我们希望C ++代码模仿这一点,我们需要使用适当的C ++代码执行每一步。

First, the inner function. 一,内在功能。 In C++, lexical scoping does not exist. 在C ++中,词汇范围不存在。 So you cannot return functions that reference variables in other scopes. 因此,您无法返回引用其他范围中的变量的函数。 You can only return a lambda that has a copy of variables from another scope. 您只能返回一个具有来自另一个范围的变量副本的lambda。 Also, lambdas cannot modify scope unless you explicitly allow it. 此外,除非您明确允许,否则lambdas无法修改范围。 Thus, the inner code must look like this: 因此,内部代码必须如下所示:

int id = 0;
return [=]() mutable { return ++id; };

That's all well and good, but now we need to create a lambda that will return this stateful lambda function. 这一切都很好,但现在我们需要创建一个lambda来返回这个有状态的lambda函数。 In C++, functions that have state are not the same as function pointers. 在C ++中,具有状态的函数与函数指针不同。 And since the type of a lambda is compiler-defined, there's no way to type its name. 由于lambda的类型是编译器定义的,因此无法输入其名称。 Therefore, we must employ std::function as the return type of the outer function. 因此,我们必须使用std::function作为外部函数的返回类型。

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

This creates a lambda function that, when called, will return an inner function with its own state. 这将创建一个lambda函数,在调用时,它将返回具有自己状态的内部函数。 State that is independent from any subsequent calls to this function. 独立于此函数的任何后续调用的状态。 Just like the JavaScript example. 就像JavaScript示例一样。

Now, that's not enough. 现在,这还不够。 Remember, your JavaScript creates the outer function, calls it, and stores only its return value. 请记住,您的JavaScript创建外部函数,调用它,并存储其返回值。 The outer function itself is discarded. 外部函数本身被丢弃。 So we need to mimic this. 所以我们需要模仿这个。 Fortunately, this is easy enough in C++; 幸运的是,这在C ++中很容易; it looks just like JavaScript: 它看起来就像JavaScript:

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

Lastly, we stick it in a variable: 最后,我们将其添加到变量中:

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

The type of uniqueID1 will be std::function<int()> . uniqueID1的类型是std::function<int()> It won't be the type of the outer function. 它不是外部函数的类型。 The outer function is just a temporary that was used to create the inner scope. 外部函数只是用于创建内部范围的临时函数。

I assume you're not asking for a literal translation, but rather how to best express this construct in C++. 我假设你不是要求字面翻译,而是如何在C ++中最好地表达这个构造。 Your JavaScript construct is in some sense "faking a constructor", and your ID generator is best expressed as a simple class in C++. 你的JavaScript构造在某种意义上是“假装构造函数”,你的ID生成器最好用C ++表示为一个简单的 Then you just make instances of that class: 然后你只需要创建该类的实例:

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

Usage: 用法:

UniqueID gen1, gen2;

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

This approach is lighter-weight than a std::function wrapper, although a straight-up lambda will produce a similar data structure (though you cannot know its type name). 这种方法比std::function包装器重量轻,尽管直接lambda会产生类似的数据结构(尽管你不知道它的类型名称)。 You can initialize value to -1 if you want the first ID to be 0 (though it might be useful to reserve 0 as a special value). 如果希望第一个ID为0,则可以将value初始化为-1 (尽管将0保留为特殊值可能很有用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将此 jQuery 代码重写为 Javascript? - How can I rewrite this jQuery code into Javascript? 我该如何重写此javascript代码,以便它将引用每个optionbox? - How can I rewrite this javascript code, so that it will refer to every optionbox? C ++ 11 std参考ECMAScript(Javascript)规范? - C++11 std ref to ECMAScript (Javascript) spec? 如何重写此代码,以便不强制从 Javascript Promise .then() 方法开始执行? - How can I rewrite this code so that execution is not forced to start from Javascript Promise .then() method? 如何检查用户是否运行chrome 11版本? (JavaScript代码)? - How can I check if the user running chrome 11 version? (javascript code)? 如何从本地驱动器上的 .js 文件中获取 JavaScript 代码并在 IE11 中运行它? - How can I grab JavaScript code from a .js file on local drive and run it in IE11? 我可以在Internet Explorer 11的调试器中修改Javascript代码吗? - Can I modify Javascript code in Internet Explorer 11's debugger? 如何在不使用JavaScript的情况下使用JQuery库来重写它? - How can I rewrite this without using JQuery library just with JavaScript? 如何重写此JavaScript行以简化阅读? (三元运算符) - How can I rewrite this JavaScript line for simpler reading? ( Ternary Operator ) 我该如何重写这些JavaScript承诺,使其变得更简单? - How can i rewrite these JavaScript promises to be less complicated?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM