I've currently trouble implementing the Visitor-Pattern in a Header-Only library in C++.
Consider following class which should support being visited by a visitor (no interface for simplicity reasions):
class Acceptor
{
void accept(Visitor* v)
{
v->visit(this);
}
};
Here is the interface for the visitors:
class Visitor
{
virtual void visit(Acceptor* t) = 0;
};
In a Header-Only lib, Acceptor.hpp must include Visitor.hpp and Visitor.hpp must include Acceptor.hpp. Since both headers are protected by Include-Guards, the later one will fail. Using forward declarations won't solve the problem, too.
For Visitor
an incomplete type of Acceptor
(aka class Acceptor;
) is sufficient. Hence, you can break the cyclic #include
s by including Visitor
in Acceptor
but not vice versa.
To demonstrate this, I made a one-file-MCVE:
class Acceptor;
class Visitor
{
friend class Acceptor;
virtual void visit(Acceptor* t) = 0;
};
class Acceptor
{
void accept(Visitor* v)
{
v->visit(this);
}
};
Note:
I had to add the friend class Acceptor
because all member functions of OPs code are private
. However, even for this the incomplete type class Acceptor
appears sufficient.
With separate files:
File visitor.h
:
#ifndef VISITOR_H
#define VISITOR_H
class Acceptor;
class Visitor
{
friend class Acceptor;
virtual void visit(Acceptor* t) = 0;
};
#endif // VISITOR_H
File acceptor.h
:
#ifndef ACCEPTOR_H
#define ACCEPTOR_H
#include "visitor.h"
class Acceptor
{
void accept(Visitor* v)
{
v->visit(this);
}
};
#endif // ACCEPTOR_H