Question

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.

Was it helpful?

Solution

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].

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top