Reputation: 33
I want to make following code snippet to work
typedef boost::function<result_type ()> functor_type;
typedef boost::variant<int, functor_type> result_type;
two types depend on each other, how to break the circular dependencies?
The Motivation
Basicly, I want to implement tail call in c++, like this
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();
}
Upvotes: 3
Views: 232
Reputation: 11181
Boost variant has two specific utilities (recursive_variant and recursive_wrapper) to do that.
Here an example using 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()>;
};
Upvotes: 1
Reputation: 1072
Please have a look at boost::recursive_variant
.
An example from the Boost.Spirit examples:
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
};
}
Upvotes: 1