Ideally, I'd like to declare the following type:
using action_t = std::function< std::vector< action_t >(void) >
This is a thunk which returns a vector of followup thunks. I was able to get this far using information from Recursive typedef function definition : std::function returning its own type :
struct RecursiveHelper
{
typedef std::vector<RecursiveHelper> rtype;
typedef std::function< rtype (void) > ftype;
RecursiveHelper( ftype f ) : func(f) {}
rtype operator()() const { return func(); }
operator ftype () { return func; }
ftype func;
};
using action_t = RecursiveHelper;
using actions_t = std::vector<RecursiveHelper>;
However, to push these things onto a stack, for instance, I have to do things like this:
std::stack<action_t> stack;
stack.push(RecursiveHelper([&visitor, &node](void){
return visitor.visitNode(node);
}));
Ideally I'd like to avoid any mention of RecursiveHelper
in code which uses this stuff, if they want a stack of action_t, they should be able to push conforming lambdas straight onto it.
Is there any way to accomplish this?
Write a constructor that accepts any function object that is convertible to ftype
and isn't RecursiveHelper
:
template<class F, class = std::enable_if_t<std::is_convertible<F, ftype>::value &&
!std::is_same<RecursiveHelper, std::decay_t<F>>::value>>
RecursiveHelper( F&& f ) : func(std::forward<F>(f)) {}
For C++11, replace something_t<...>
with typename something<...>::type
.