I'm implementing an acyclical visitor in my project and having some difficulties with the requisite dynamic_cast. The setup looks something like this:

class Visitor; 
class Entity
{
public:
	virtual void accept(Visitor &v) const = 0;
};

class MyClass ; 
class MyClassVisitor
{ 
public: 
	virtual void visit(const MyClass &obj) = 0; 
}; 

class MyClass : public Entity
{ 
public: 
	virtual void accept(Visitor &v) const 
	{ 
		MyClassVisitor *rcvr = dynamic_cast<MyClassVisitor*>(&v); 
		if(rcvr) 
			rcvr->visit(*this); 
	} 
}; 

class SpecificVisitor : public Visitor, public MyClassVisitor
{
public:
	virtual void visit(const MyClass &obj)
	{
		//...
	}
}

However, this doesn't compile, and I'm having trouble figuring out why. With Visual Studio 2008 I get "Error C681: 'Visitor *' : invalid expression type for dynamic_cast". From what I understand, this sort of cross casting SHOULD work with dynamic cast, but the compiler is choking on it.

I've done searches on google, but I haven't been able to turn anything up. Anybody have any ideas?

You have only forward declared Vistor in this code snippet so it does compile at line 26 which requires the full declaration of visitor.

Assuming this is a mistake that doesn't exists in your actual code and the the missing ; on line 33 is a typo then have you declared any Virtual functions in visitor? You can only dynamic_cast from a class with virtual functions defined in it. Note that any class in a hierarchy like this one should have its destructor declared virtual at a minimum.

If I put in a ; on line 33 and replace class Visitor; with

class Visitor
{
public:
    virtual ~Visitor(){}
};

it compiles for me.

Ah... this could well be my issue, thanks. The actual definition of the Visitor base class is supplied elsewhere. Going to need to figure out how to juggle my dependencies to make it work.

I'll get back to you if it fixes the problem.

[edit] Yeah, that fixes it. Thanks!

Edited 6 Years Ago by Ian Morrison: n/a

This article has been dead for over six months. Start a new discussion instead.