Shr*_*roy 3 c++ lambda tail-call-optimization c++11
我的试探性答案是否定的,如以下测试代码所示:
#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 ()
Run Code Online (Sandbox Code Playgroud)
有没有办法强制编译器优化lambdas中的递归尾调用?
在此先感谢您的帮助.
编辑
我只想澄清一下,我想问一下C++ 11是否优化了lambdas中的递归尾调用.我正在使用Visual Studio 2012,但如果绝对知道GCC进行了所需的优化,我就可以切换环境.
你实际上并没有在"lambda"代码中进行尾调用,至少不是直接调用.std::function是一个多态函数包装器,这意味着它可以存储任何类型的可调用实体.C++中的lambda具有唯一的,未命名的类类型,并且不是std::function对象,它们只能存储在它们中.
因为std::function使用类型擦除,它必须跳过几个箍来调用最初传递给它的东西.这些箍通过虚函数或函数指针完成功能模板特化和void*.
间接的唯一性使得它非常难以优化,以通过他们看.同样,编译器很难看到std::function并判断你是否有尾递归调用.
另一个问题是r可以从内部r或同时更改,因为它是一个简单的变量,突然间你不再有递归调用了!使用功能标识符,这是不可能的,它们不能在中途改变含义.
我只想澄清一下,我想问一下C++ 11是否优化了lambdas中的递归尾调用.
C++ 11标准描述了抽象机器上的工作程序的行为,而不是编译器如何优化内容.实际上,只有在不改变程序的可观察行为的情况下才允许编译器进行优化(copy-elision /(N)RVO是例外).
| 归档时间: |
|
| 查看次数: |
1116 次 |
| 最近记录: |