У меня есть случай, когда я могу передать lambda в std :: sort, и я также могу предоставить предикат, вызвав функцию, которая возвращает std :: function, которая обертывает эту же lambda, но если я попытаюсь вызвать аналогичную функцию который позволяет мне указывать указатель на функцию-член, этот компилируется, но не выполняется во время выполнения.
Это работает:
std::sort(myContainer.begin(), myContainer.end(), [&](type lhs, type rhs)
{
return MyMemberFunction(lhs, rhs);
});
И это работает:
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());
Но это не работает:
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());
Когда я пытаюсь сделать это, это последний общий способ, и я перехожу через отладчик, когда std :: sort вызывает предикат, он вступает в то, что я назвал ReturnGeneralPred выше, и Func, кажется, не определен, как если бы это был локальный переменная, выходящая за рамки.
На данный момент я могу получить такую же функциональность, потеряв некоторую родословность, но мне было интересно, может ли быть способ сделать то, что я пытался сделать.
Func
является локальным для ReturnGeneralPred
, а лямбда используется, когда Func
выходит за рамки (висящий указатель).
Capture Func
копией должен решить вашу проблему:
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;
}
или используйте синтаксис [=]
вместо явного захвата [this, Func]
.
Func
по значению, а не по ссылке.