以下代码给出了分段错误。调试之后,我发现问题可以通过将lambda声明为auto而不是Function来解决。为什么会这样?
#include <functional>
#include <iostream>
#include <vector>
typedef std::vector<double> Vec;
typedef std::function<const Vec&(Vec)> Function;
int main()
{
//Function func = [](const Vec& a)->Vec /*this give me segfault*/
auto func = [](const Vec& a)->Vec /*this work just fine??*/
{
Vec b(2);
b[0] = a[0] + a[1];
b[1] = a[0] - a[0];
return b;
};
Vec b = func(Vec{1,2});
std::cout << b[0] << " " << b[1] << "\n";
return 0;
}
如果我可以将其声明为函数,那将会很棒 将此lambda表达式传递给其他类。
当func声明为Function时,我所遇到的错误是:
编程接收信号SIGSEGV,分段故障。 0x0000000000401896在std :: vector&gt; :: size(this = 0x0)/usr/include/c++/5/bits/stl_vector.h:655 655 {return size_type(this-&gt; _M_impl._M_finish - this-&gt; _M_impl._M_start); }
(gdb)回溯
#d 0x0000000000401896在std :: vector&gt; :: size(this = 0x0)/usr/include/c++/5/bits/stl_vector.h:655
std :: vector&gt; :: vector中的#1 0x00000000004015aa(这= 0x7fffffffdc50,__ x =) 在/usr/include/c++/5/bits/stl_vector.h:320
main()中的#2 0x0000000000400d12位于test.cxx:18
答案 0 :(得分:6)
(Vec) -> const Vec&
相当于一个看起来像(const Vec&) -> Vec
的lambda。您传递了std::function
。
std::function
接受它(您可以将值传递给期望const引用的函数)。
分段错误最有可能是你的lambda(临时)的返回值固有的未定义行为被绑定到operator()
std::function
中的const引用;该引用正在Record
之外返回,这会立即使其成为悬空参考。
答案 1 :(得分:1)
您需要注意函数类型,如果使用正确的函数类型它应该可以正常工作;
typedef std::function<Vec(const Vec&)> Function;
使用较少的对象包装器和更多传统功能可能会使问题更加清晰。
一旦你通过对象移除间接,它归结为:
// const Vec& -> Vec
std::vector<double> the_lambda(const std::vector<double>& x)
{
return x;
}
// Vec -> const Vec&
const std::vector<double>& the_function(std::vector<double> x)
{
return the_lambda(x);
}
int main()
{
std::vector<double> v = {1, 2};
std::vector<double> lv = the_lambda(v); // OK.
std::vector<double> fv = the_function(v); // Undefined.
}
这编译,但是g ++警告the_function
返回对临时的引用,这正是std::function
所发生的事情(但没有提到编译器的提示)。
(我确信允许在std::function
中转换返回值是一个错误。如果你使用的是函数指针,你就不会侥幸逃脱它,并且假设是C ++要比