c++ - C++11 是否优化了 lambda 中的尾递归调用?

标签 c++ lambda c++11 tail-call-optimization

我的暂定答案是否定的,如以下测试代码所示:

#include <functional>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

void TestFunc (void);
int TestFuncHelper (vector<int>&, int, int);

int main (int argc, char* argv[]) {
    TestFunc ();
    return 0;
} // End main ()

void TestFunc (void) {
    // Recursive lambda
    function<int (vector<int>&, int, int)> r = [&] (vector<int>& v_, int d_, int a_) {
        if (d_ == v_.size ()) return a_;
        else return r (v_, d_ + 1, a_ + v_.at (d_));
    };
    int UpperLimit = 100000; // Change this value to possibly observe different behaviour
    vector<int> v;
    for (auto i = 1; i <= UpperLimit; i++) v.push_back (i);
    // cout << TestFuncHelper (v, 0, 0) << endl; // Uncomment this, and the programme works
    // cout << r (v, 0, 0) << endl; // Uncomment this, and we have this web site
} // End Test ()

int TestFuncHelper (vector<int>& v_, int d_, int a_) {
    if (d_ == v_.size ()) return a_;
        else return TestFuncHelper (v_, d_ + 1, a_ + v_.at (d_));
} // End TestHelper ()

有没有办法强制编译器优化 lambda 中的递归尾调用?

预先感谢您的帮助。

编辑

我只是想澄清一下,我想问的是 C++11 是否优化了 lambda 中的递归尾调用。我正在使用 Visual Studio 2012,但如果绝对知道 GCC 进行了所需的优化,我可以切换环境。

最佳答案

您实际上并没有在“lambda”代码中进行尾调用,至少不是直接进行。 std::function 是一个多态函数包装器,这意味着它可以存储任何类型的可调用实体。 C++ 中的 lambda 具有唯一的未命名类类型,并且不是 std::function 对象,它们只能存储在其中。

由于 std::function 使用类型删除,它必须跳过几个环才能调用最初传递给它的东西。这些循环通常使用虚函数或指向函数模板特化和 void* 的函数指针完成。

间接的唯一性质使优化器非常难以看穿它们。同样,编译器很难看穿 std::function 并决定您是否有尾递归调用。

另一个问题是 r 可能会在 r 内或同时发生更改,因为它是一个简单的变量,突然间您不再需要递归调用了!使用函数标识符,这是不可能的,它们不能中途改变含义。

I just wanted to clarify that I meant to ask if C++11 optimizes recursive tail calls in lambdas.

C++11 标准描述了抽象机器上的工作程序的行为方式,而不是编译器如何优化东西。事实上,编译器只允许在不改变程序的可观察行为的情况下进行优化(copy-elision/(N)RVO 是异常(exception))。

关于c++ - C++11 是否优化了 lambda 中的尾递归调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13113929/

相关文章:

javascript - 无法编译android cocos2d文件--Android-Studio

C++ - 按字母顺序排列字符串

python - jython lambda 函数

amazon-web-services - 在 AWS Lambda 中获取错误指标但在日志中找不到任何错误

c++ - 使用 TBB parallel_for_each() 减少原子计数器

c++ - ublas 矩阵表达式教程/示例

python - 数组包括来自 C++ 中的 python 的范围

c++ - Visual Studio 2015 中的广义 Lambda 捕获表达式 : Compiler bug or correct behavior?

c++ - 根据用户配置在运行时链接共享对象

c++ - C++ 类上的 std::move 不会 move 所有成员?