В идеале я хотел бы объявить следующий тип:
using action_t = std::function< std::vector< action_t >(void) >
Это thunk, который возвращает вектор последующих thunks. Я смог получить это далеко, используя информацию из Определение функции рекурсивного определения типа: std :: function, возвращающая свой собственный тип :
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>;
Однако, чтобы поместить эти вещи в стек, например, мне нужно сделать что-то вроде этого:
std::stack<action_t> stack;
stack.push(RecursiveHelper([&visitor, &node](void){
return visitor.visitNode(node);
}));
В идеале я бы хотел избежать упоминаний о RecursiveHelper
в коде, который использует этот материал, если им нужен стек action_t, они должны иметь возможность вставлять прямо в него соответствующие лямбды.
Есть ли способ сделать это?
Напишите конструктор, который принимает любой функциональный объект, который можно преобразовать в ftype
и не 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)) {}
Для C ++ 11 замените something_t<...>
с typename something<...>::type
,