The following code yields a Segmentation Fault on the y = anotherFunctor() line. As far as I understand, this happens because the globalFunctor variable does not exist when anotherFunctor is created. But why does it work if I replace std::function<int(int)> with GlobalFunctor? How would I fix it?
#include <functional>
struct GlobalFunctor
{
int operator()() const { return 42; }
};
extern GlobalFunctor globalFunctor;
struct AnotherFunctor
{
AnotherFunctor() : g_(globalFunctor) {}
int operator()() const { return g_(); }
const std::function<int()>& g_;
} anotherFunctor;
GlobalFunctor globalFunctor;
int main()
{
AnotherFunctor af;
int x = af();
int y = anotherFunctor();
int z = x + y;
return 0;
}
Edit: I tried compiling this with clang instead of gcc and it warns me about binding reference member 'g_' to a temporary value — but it crashes when compiling this. Would the cast to std::function create a temporary reference?
At
g_(globalFunctor),globalFunctorhas to be converted to anstd::functionbecause it is of typeGlobalFunctor. So a temporary is produced and this is bound to the constant reference. You could think of the code as doingg_(std::function<int()>(globalFunctor)). However, this temporary only lives until the end of the constructor, as there is a special rule in C++ saying that temporaries in member initializer lists only live until the end of the constructor. This leaves you with a dangling reference.The code works when you replace
std::function<int(int)>withGlobalFunctorbecause no conversion is involved. Therefore, no temporaries are produced and the reference directly refers to the global object.You either need to not use references and store a
std::functioninternally or make a globalstd::functionand have a reference to that.