2012-12-14 4 views
3

Я хочу сделать следующий фрагмент кода для работырекурсивные типы шаблонов

typedef boost::function<result_type()> functor_type; 
typedef boost::variant<int, functor_type> result_type; 

два типа зависят друг от друга, как разбить круговые зависимости?


Мотивация

Основном, я хочу, чтобы реализовать хвостовую вызов в C++, как этот

template<typename ResultT> 
struct TailCall 
{ 
    typedef ResultT result_type; 
    typedef boost::function<ret_type()> continuation_type; 
    typedef boost::variant<result_type, continuation_type> ret_type; 

    TailCall(const continuation_type& init) : next(init) {} 

    result_type operator()() 
    { 
     while (true) { 
      ret_type r = next(); 
      result_type *result = boost::get<result_type>(&r); 
      if (result) 
       return *result; 
      else 
       next = boost::get<continuation_type>(r); 
     } 
    } 

private: 
    continuation_type next; 
}; 

TailCall<int>::ret_type fibonacci_impl(int term, int val, int prev) 
{ 
    if (term == 0) return prev; 
    if (term == 1) return val; 
    return boost::bind(fibonacci_impl, term-1, val+prev, val); 
} 

int fibonacci(int index) 
{ 
    TailCall<int> fib(boost::bind(fibonacci_impl, index, 1, 0)); 
    return fib(); 
} 
+0

Зачем вам это нужно? –

+0

Я боюсь, что это невозможно сделать :( – Pubby

+1

Это может помочь, если вы объясните (путем редактирования вопроса), что вы пытаетесь сделать, и как вы собираетесь использовать эти типы typedef. – hyde

ответ

1

подталкивания вариант имеет два специальных утилит (recursive_variant и recursive_wrapper), чтобы сделать это.

Вот пример с использованием recursive_wrapper

struct functor_type; 

typedef boost::variant<int, 
      boost::recursive_wrapper<functor_type> > result_type; 

struct functor_type : public boost::function<result_type()> { 
     using boost::function<result_type()>::boost::function<result_type()>; 
}; 
+0

Спасибо, это работает. – user1903494

+0

На самом деле, я был бы признателен, если кто-то может опубликовать решение, которое использует recursive_variant. Мне не удастся получить эту работу для этого случая. – sbabbi

1

Пожалуйста, посмотрите на boost::recursive_variant.

Пример из Boost.Spirit примеров:

struct mini_xml; 

    typedef 
     boost::variant< 
      boost::recursive_wrapper<mini_xml> 
      , std::string 
     > 
    mini_xml_node; 

    struct mini_xml 
    { 
     std::string name;       // tag name 
     std::vector<mini_xml_node> children;  // children 
    }; 
} 
Смежные вопросы