Search code examples
c++oopheader-only

Visitor-Pattern in C++ in a Header-Only Environment


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.


Solution

  • For Visitor an incomplete type of Acceptor (aka class Acceptor;) is sufficient. Hence, you can break the cyclic #includes 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);
        }
    };
    

    Live Demo on coliru

    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