I have a question about boos::function. I have a function with a boost::function as a parameter. This boost::function has the return value void(). But I call the function ChangeWorking(...) couple times in my code and for one case I need a return value from the boost::function. Has anybody an idea how to solve that problem?
The actual function looks like this:
void CElmWorkingPropertyList::ChangeWorking( boost::function<void( CPamWorking* )> a_pFunc, bool a_bAlignmentChange )
{
//do some stuff
CPamWorkingPtr pWork = IsBlockEditActive() ? pWorkSource : pWorkSource->Clone();
if (!pWork)
{
ASSERT( false ); // current working needs to be there
continue;
}
pWork->SetComponent( pWorkSource->GetComponent() );
if (a_pFunc)
{
a_pFunc(pWork.get());
}
//do more stuff
}
But I need also a function, which look like this (This function is not implemented):
void CElmWorkingPropertyList::ChangeWorking( boost::function<CPamWorking*( CPamWorking* )> a_pFunc, bool a_bAlignmentChange )
{
//do same stuff
if (a_pFunc)
{
pWork = a_pFunc(pWork.get());
}
//do more same stuff
}
Is that possible or do I have to write a new function?
CodePudding user response:
Can you change the type of a_pFunc
(Assumed to be a shared_ptr
) to boost::function<void( std::shared_ptr<CPamWorking>&)> a_pFunc
, so that you can decide whether to change the p_worker
you passed by in the implementation of a_pFunc
?
CodePudding user response:
I would probably not hardcode function<>
in the first place. With some C 17:
#include <cassert>
#include <functional>
#include <iostream>
#include <memory>
#include <type_traits>
struct CComponent {
virtual ~CComponent() = default;
};
using CPamWorkingPtr = std::shared_ptr<struct CPamWorking>;
struct CPamWorking : public std::enable_shared_from_this<CPamWorking> {
virtual ~CPamWorking() = default;
virtual CPamWorkingPtr Clone() = 0;
CComponent const* SetComponent(CComponent const* cc) { return std::exchange(m_component, cc); }
CComponent const* GetComponent() const { return m_component; }
private:
CComponent const* m_component = nullptr;
};
struct ConcretePamWorking : CPamWorking {
virtual CPamWorkingPtr Clone() override {
return std::make_shared<ConcretePamWorking>();
}
};
struct CElmWorkingPropertyList {
bool IsBlockEditActive() const { return false; }
template <typename Func>
void ChangeWorking(
Func a_pFunc = [](CPamWorkingPtr) {}, bool a_bAlignmentChange = false)
{
for (CPamWorkingPtr pWork = IsBlockEditActive() && pWorkSource
? pWorkSource
: pWorkSource->Clone();
pWork;) {
if (!pWork) {
assert(false); // current working needs to be there
continue;
}
pWork->SetComponent(pWorkSource->GetComponent());
bool constexpr returns_work =
std::is_assignable_v<CPamWorkingPtr, decltype(a_pFunc(pWork))>;
if constexpr (returns_work) {
std::cout << "DEBUG: setting returned work\n";
pWork = a_pFunc(pWork);
} else {
std::cout << "DEBUG: no returned work\n";
a_pFunc(pWork);
break;
}
}
}
private:
CPamWorkingPtr pWorkSource = std::make_shared<ConcretePamWorking>();
};
int main() {
CElmWorkingPropertyList wpl;
wpl.ChangeWorking(
[](CPamWorkingPtr w) { std::cout << "void work with " << w.get() << "\n"; });
unsigned counter = 10;
wpl.ChangeWorking([&counter](CPamWorkingPtr w) {
std::cout << "non-void work with " << w.get() << "\n";
return counter-- ? w->Clone() : nullptr;
});
}
Prints eg Live On Coliru
DEBUG: no returned work
void work with 0xe0dc70
DEBUG: setting returned work
non-void work with 0xe0dc70
DEBUG: setting returned work
non-void work with 0xe0ecc0
DEBUG: setting returned work
non-void work with 0xe0dc70
DEBUG: setting returned work
non-void work with 0xe0ecc0
DEBUG: setting returned work
non-void work with 0xe0dc70
DEBUG: setting returned work
non-void work with 0xe0ecc0
DEBUG: setting returned work
non-void work with 0xe0dc70
DEBUG: setting returned work
non-void work with 0xe0ecc0
DEBUG: setting returned work
non-void work with 0xe0dc70
DEBUG: setting returned work
non-void work with 0xe0ecc0
DEBUG: setting returned work
non-void work with 0xe0dc70