Here is the code:
#include <vector>
#include <functional>
class TestClass {
public:
const std::vector<int> &getStuff() const {
return callback();
}
protected:
std::function<const std::vector<int> &()> callback = []() {
static const std::vector<int> dummy;
return dummy;
};
};
int main()
{
TestClass test;
const auto& vec = test.getStuff();
vec.size(); // segfault
return 0;
}
I don't understand why it should behave like this. I suspect some "known" rule about lambdas or std::function
s but I cannot seem to find the right keywords for this problem so here I am.
Tested on GCC 11 and Clang 14 Ubuntu.
With this lambda:
[]() {
static const std::vector<int> dummy;
return dummy;
};
The compiler infers that the return value is std::vector<int>
by value (and not a reference to std::vector<int>
).
Then when it is converted to a std::function<const std::vector<int> &()>
the std::function
will return a reference to the temporary copy returned from the lambda.
This reference is dangling and hence your SEGFAULT.
In order to fix it, you can specify the return type for the lambda explicitly:
//---vvvvvvvvvvvvvvvvvvvvvvvvvv--
[]() -> const std::vector<int>& {
static const std::vector<int> dummy;
return dummy;
};
As @Evg commented below, you can also use auto &
to achieve the same result (the compiler will deduce the proper type and use a referece due to the &
):
[]() -> auto & {
// ...
}