Q:

C++ generic double-dispatcher/visitor

I'm trying to reduce the boilerplate code for the visitor/double dispatcher pattern. First I've created a way to enforce the dispatcher to declare the dispatch(T) function for every type supported and also a dispatch_gen(T) for the generic case which I don't need to implement. This is not too hard:
/*
A generic way to get the type of a base class using a tag function
*/
template <typename T, typename U>
T base_of(U T::*);

/*
Generic dispatcher
*/
template <typename... T>
struct double_dispatcher_impl;

template <typename Head>
struct double_dispatcher_impl<Head> {
    virtual void dispatch(Head*) = 0;
};

template <typename Head, typename... Tail>
struct double_dispatcher_impl<Head, Tail...> : public double_dispatcher_impl<Tail...> {
    using double_dispatcher_impl<Tail...>::dispatch;

    virtual void dispatch(Head*) = 0;
};

template <typename... T>
struct double_dispatcher;

template <typename Head, typename... Tail>
struct double_dispatcher<Head, Tail...> : public double_dispatcher_impl<Head, Tail...> {
    using Base = decltype(base_of(&Head::dispatch_id));
    using double_dispatcher_impl<Head, Tail...>::dispatch;

    virtual void dispatch_gen(Base* b) { b->dispatch(this); }
};

The dispatch_id() is just a hacky way to get the base class, it server as a tag. Now the base class for a visitable/dispatchable:
template <typename D>
struct double_dispatchable {
    virtual void dispatch(D* d) { }
    void dispatch_id() { }
};

This gives me a relatively "nice" usage. Here's a simple example:
struct Circle;
struct Rect;
struct Triangle;
typedef double_dispatcher<Circle, Rect, Triangle> shape_disp;

struct Shape : public double_dispatchable<shape_disp> { };
struct Circle : public Shape    { void dispatch(shape_disp* disp) { disp->dispatch(this); } };
struct Rect : public Shape      { void dispatch(shape_disp* disp) { disp->dispatch(this); } };
struct Triangle : public Shape  { void dispatch(shape_disp* disp) { disp->dispatch(this); } };

struct my_dispatcher : public shape_disp {
    void dispatch(Circle* c)    { std::cout << "Circle!" << std::endl; }
    void dispatch(Rect* c)      { std::cout << "Rect!" << std::endl; }
    void dispatch(Triangle* c)  { std::cout << "Triangle!" << std::endl; }
};

Now there's still a lot of repetitive code in there (the callbacks for the subclasses). How could I improve the pattern? Can I remove the repetitive code with metaprogramming and generics, without using macros?

A:

I have implemented something like that in one of my projects, the trick is to use CRTP to pass the Child type to the parent.
This is a simplified code :
#include "collisions.h"
#define SHAPES Box, Sphere, Mesh
class Box;
class Sphere;
class Mesh;

class Geometry;

// Collidable defines all the pure virtual functions.
template <typename... Shapes>
struct Collidable;

template <>
struct Collidable<> {
    virtual bool collide(const Geometry* obj) const = 0 ;
};

template <typename Shape, typename... Others>
struct Collidable<Shape, Others...> : Collidable<Others...> {
    using Collidable<Others...>::collide;
    virtual bool collide(const Shape* obj) const = 0;
};

// Geometry inherits from Collidable and is our common base class.
class Geometry : public Collidable<SHAPES> {
    public:
        Geometry();
        virtual ~Geometry();
        glm::vec3 getPosition() const;

    private:
        glm::vec3 m_pos;
};

// Dispatcher inherits from Geometry and implements one dispatch function
// for all the given type and the Geometry one.
template <class T, typename... Shapes>
struct Dispatcher;

template <class T>
struct Dispatcher<T> : public Geometry {
    bool collide(const Geometry* obj) const final override {
        return obj->collide(static_cast<const T*>(this));
    }
};

template <class T, typename Shape, typename... Others>
struct Dispatcher<T, Shape, Others...> : public Dispatcher<T, Others...> {
    using Dispatcher<T, Others...>::collide;
    bool collide(const Shape* obj) const final override {
        return Collisions::collide(obj, static_cast<const T*>(this));
    }
};

// Shape<T> is our generic dispatch class.
template <class T>
class Shape : public Dispatcher<T, SHAPES> {};

With all shapes defined like:
class Sphere : public Shape<Sphere> {...};
Of course, all the corresponding Collisions::collide(*,*) must be declared.
I am not very familiar with template meta-programming, so I couldn't find a clean solution to replace the #define SHAPES Box, Sphere, Mesh and the classes declarations at the beginning of the file.
Furthermore, I don't know if a good compiler can optimize virtual calls using de-virtualization (that's why I tried to add final keyword).

