Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-10-22 11:03:49


Timothy Ritchey wrote:
> I have an interpreter that uses a visitor pattern while performing a
> reduction of the program tree. As part of the visitor pattern, each
> class that can be a node in the tree must respond to:
>
> virtual void accept(Visitor& v);
>
> where each node then implements by calling visitor with itself using
> the proper type. The function calls in visitor are like:
>
> void visit(shared_ptr<Node> node);
> void visit(shared_ptr<Type> node);
> etc.
>
> (where Type is a descendant of node BTW).

Interesting. Why do you need to pass a shared_ptr to the visitor?

> Normally with the visitor pattern (GOF style in this case), the
> implementation of accept is simply:
>
> void Node::accept(Visitor &v) {
> v.visit(this);
> }
>
> I've tried adding enable_shared_from_this<...> as a superclass of my
> nodes, and returning shared_from_this(), which works in some cases,
> but in others just seems to hang. These occur in classes that are a
> little more complex. For example, I have a TypeTemplate<T> class that
> wraps to underlying types TypeTemplate<int>, TypeTemplate<float>,
> TypeTemplate<etc>. I've tried adding
> enable_shared_from_this<TypeTemplate<T> >, and then having an
> implmentation
>
> void TypeTemplate<T>::accept(Visitor &v) {
> v.visit(enable_shared_from_this<TypeTemplate<T>
> >::shared_from_this()); }
>
> but it just hangs on both vc7.1 on windows and Xcode on OS X. (I had
> to add the extra scoping because I got complaints that
> "shared_from_this() was ambiguous in multiple inheritance.")

shared_from_this() shouldn't hang; can you simplify this down to a minimal
example?

Since shared_from_this() is ambiguous, I take it that your class has several
enable_shared_from_this base classes. This doesn't work; at most one of them
will be initialized properly, the rest will (should) just throw
bad_weak_ptr.

You'll need to try to eliminate the multiple enable_shared_from_this bases.
This can typically be done by following the "non-leaf classes should be
abstract" advice. IOW:

class Node: public enable_shared_from_this<Node> {};
class Type: public Node, public enable_shared_from_this<Type> {};

needs to be refactored as:

class AbstractNode { /* pure virtuals */ };
class AbstractType: public AbstractNode { /* pure virtuals */ };
class Node: public AbstractNode, public enable_shared_from_this<Node> {};
class Type: public AbstractType, public enable_shared_from_this<Type> {};

This is the best advice I can offer without more information. :-) I hope
that it helps.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net