C++ std::function, которая возвращает вектор своего собственного типа (снова рекурсивные типы)

В идеале я хотел бы объявить следующий тип:

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, они должны быть в состоянии вставить прямо в него соответствующие лямбды.

Есть ли способ сделать это?

1 ответ

Решение

Напишите конструктор, который принимает любой функциональный объект, который можно преобразовать в 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,

Другие вопросы по тегам