Reputation: 542
I have a case where I can pass a lambda to std::sort, and I can also supply the predicate by calling a function that returns a std::function which wraps this same lambda, but, if I try to call a similar function which allows me to specify a pointer to member function, this compiles but fails at run time.
This works:
std::sort(myContainer.begin(), myContainer.end(), [&](type lhs, type rhs)
{
return MyMemberFunction(lhs, rhs);
});
And this works:
std::function<bool(type,type)> ReturnPred()
{
std::function<bool(type,type)> pred = [&](type lhs, type rhs)
{
return MyMemberFunction(lhs, rhs);
};
return pred;
}
std::sort(myContainer.begin(), myContainer.end(), ReturnPred());
But this does not work:
std::function<bool(type,type)> ReturnGeneralPred(
bool(MyClass::Func*)(type lhs, type rhs))
{
std::function<bool(type,type)> pred = [&](type lhs, type rhs)
{
return (this->*Func)(lhs, rhs);
};
return pred;
}
std::function<bool(type,type)> ReturnThisPred()
{
return ReturnGeneralPred(&MyClass::MyMemberFunction);
}
std::sort(myContainer.begin(), myContainer.end(), ReturnThisPred());
When I try to do it this last generic way and I step through the debugger, when std::sort calls the predicate, it steps into what I've call ReturnGeneralPred above, and Func seems to be undefined, as though it was a local variable that went out of scope.
At the moment I can get the same functionality by losing some genericness, but I was wondering if maybe there's a way to accomplish what I was trying to do.
Upvotes: 0
Views: 132
Reputation: 217663
Func
is local to ReturnGeneralPred
, and the lambda is used when Func
is out of its scope (dangling pointer).
Capture Func
by copy should solve your issue:
std::function<bool(type,type)> ReturnGeneralPred(bool(MyClass::Func*)(type lhs, type rhs))
{
std::function<bool(type,type)> pred = [this, Func](type lhs, type rhs)
{
return (this->*Func)(lhs, rhs);
};
return pred;
}
or use [=]
syntax instead of explicit capture [this, Func]
.
Upvotes: 1