C++0x 闭包的未定义行为:I
考虑这个例子:
#include <iostream>
#include <functional> // std::function
#include <vector> // std::vector
#include <algorithm> // std::for_each
int main(){
auto adder = [](int x) {
return [&](int y) {
return x+=y;
};
};
std::vector < std::function<int(int)> > vec;
vec.push_back(adder(1));
vec.push_back(adder(10));
std::for_each(vec.begin(), vec.end(), [](std::function<int(int)> f){std::cout << f(33) << " ";});
std::cout << std::endl;
}
我们期望整数 34 和 43 43 和 76,但 gcc 4.6.0 却生成“内部编译器错误:分段错误” ”。代码有什么问题吗?
编辑:此处讨论了其他几个示例。
Consider the example:
#include <iostream>
#include <functional> // std::function
#include <vector> // std::vector
#include <algorithm> // std::for_each
int main(){
auto adder = [](int x) {
return [&](int y) {
return x+=y;
};
};
std::vector < std::function<int(int)> > vec;
vec.push_back(adder(1));
vec.push_back(adder(10));
std::for_each(vec.begin(), vec.end(), [](std::function<int(int)> f){std::cout << f(33) << " ";});
std::cout << std::endl;
}
One expects the integers 34 and 43 43 and 76, but instead gcc 4.6.0 produces "internal compiler error: Segmentation fault". What is wrong with the code?
Edit: Several other examples are discussed here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
(编辑:这当然不能解释 ICE;我太仓促地阅读了原始问题。)
代码中的一个问题是从adder
函数返回的 lambda 表达式包含对不再存在的x
变量的悬空引用。通过副本([=]
或[i]
)而不是引用([&]
)捕获,一切都应该正常。(Edit: this certainly does not explain the ICE; I read the original question too hastily.)
TheOne problem in that code is that the lambdas returned from theadder
function contain dangling references to thex
variable that no longer exists. Capture by copy ([=]
or[i]
) instead of a reference ([&]
) and everything should work.看来,在您的示例中,无法省略 Trailing-return-type 。以下是标准(5.1.2 Lambda 表达式)的摘录:
您示例中的返回值不能用于上述转换。以下显式添加返回类型的代码可在 VS 2010 中编译:
It seems, that in your example trailing-return-type cannot be omitted. Here is excerpt from standard (5.1.2 Lambda expressions):
Returned value in your example cannot be used for conversions mentioned above. Following code with explicitely added return type compiles in VS 2010:
你完全没有抓住要点。对 std::function 的需求非常非常明显。
你究竟如何创建一个在运行时与编译时事实不同的向量,就像其中包含的类型一样?这在逻辑上是不可能的——除非您使用诸如 std::function 之类的抽象。
当然,如果您只想要其中一种 lambda 类型,那么您根本不需要
std::function
。不过这种情况相对较少。MSVC 实际上不会编译这个小片段,但我认为这是一个错误,并且根据编译器的报告判断,我希望它能够在那里编译并且确实可以正常工作。
You're just completely missing the point. The need for
std::function
is very, very obvious.std::function
does.How on earth could you ever create a vector that varies at run-time a compile-time fact, like the type contained within it? That's just logically impossible- unless you use an abstraction such as
std::function
.Of course, if you only ever want one lambda type within, then you don't need
std::function
at all. This is relatively rare though.MSVC won't actually compile this little snippet, but I think that's a bug and judging by the reports of your compiler, I expect that it will compile there and indeed work correctly.