3

次のコードスニペットを機能させたい

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

2 つのタイプが相互に依存しています。循環依存関係を解消するにはどうすればよいですか?


動機

基本的に、このように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();
}
4

2 に答える 2

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
    };
}
于 2012-12-14T09:15:56.717 に答える
1

Boost バリアントには、それを行うための 2 つの特定のユーティリティ (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()>;
};
于 2012-12-14T09:44:10.993 に答える