So here is the situation: I have two classes with static inheritance through CRTP. The base class has a run method that calls the derived method with a variadic template so that the arguments are flexible. Now the derived class contains a function object. The derived class has the implementation that is called by the base class. It may seem unnecessary but in the full version of this code more commands than just the contained function are run. Next there is a method that converts the function to a bool(void) function by binding all the variadic arguments, and instance to the the method CrtpBase::Run
. This is where I am having an issue. I have tried two different approached, the version using a lambda is commented out. Neither method works. My goal is to have VoidFunction
bind all the parameters so that I can execute the function at my leisure without the arguments. What am I doing wrong here?
#include <functional>
#include <utility>
template <typename D>
struct CrtpBase {
template <typename ... Args>
bool Run(Args&& ... args) const {
return static_cast<D&>(*this).Impl(std::forward<Args>(args) ...);
}
};
template <typename ... Args>
struct CrtpDerived : public CrtpBase<CrtpDerived<Args ...>> {
CrtpDerived(std::function<bool(Args ...)> function) : runable(std::move(function)) {}
bool Impl(Args&& ... args) const {
return this->runable(std::forward<Args>(args) ...);
}
std::function<bool(Args ...)> runable;
};
template <typename D, typename ... Args>
std::function<bool()> VoidFunction(CrtpBase<D> base, Args&& ... args) {
// return [&base, &args ...]()->bool{return CrtpBase<D>::template Run<Args ...>(base);};
return std::bind(CrtpBase<D>::template Run<Args ...>, base, std::forward<Args>(args) ...);
}
int main(int argc, char** argv) {
std::function<bool(int&)> fn = [](int& a)->bool{a /= 2; return (a % 2) == 1;};
CrtpDerived<int&> derived(fn);
int x = 7;
auto voided = VoidFunction(derived, x);
bool out = voided();
if ((x == 3) and (out == true)) {
return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
}
}
Edits:
- Fixed typo in final test
(out == false)
became(out == true)