Boost :: Clase de Python con plantillas de funciones: ¿Cómo agregar instancias desde el exterior?

Resumen

¿Hay alguna manera (en C ++, no en Python) de agregar instancias adicionales de plantillas de funciones para una clase en Boost :: Python desde el exterior (por inyección, reabrir la definición, registrar las instancias necesarias, etc.)?

Antecedentes

Dada una clase (no una plantilla de clase) que contiene miembros que son plantillas de función, quiero generar enlaces de Python usando Boost :: Python.

Sin embargo, como estoy escribiendo una biblioteca, no sé de antemano con qué parámetros de plantilla se llamarán las funciones miembro. Eso significa que no puedo enumerarlos en la definición de clase Boost :: Python.

Ejemplo

Digamos que tenemos una claseTheClass que tiene plantillas de funciones (con sobrecargas) y dos clases de pruebaSomeClass yOtherClass Me gusta esto:

Definiciones de clase
#include <iostream>
#include <string>

class SomeClass
{
public:
    std::string Name()
    {
        return "SomeClass";
    }
};

class OtherClass
{
public:
    std::string Name()
    {
        return "OtherClass";
    }
};

class TheClass
{
public:

    template <class T>
    void Foo   (T& arg)
    {
        std::cout << "Called Foo(" << arg.Name() << ")" << std::endl;
    }

    template <class T>
    void Bar   (T& arg, std::string param)
    {
        std::cout << "Called Bar(" << arg.Name() << ", " << param << ")" << std::endl;
    }

    template <class T>
    void Bar   (T& arg, int param)
    {
        std::cout << "Called Bar(" << arg.Name() << ", " << param << ")" << std::endl;
    }

};

Luego uso este código para exportar todo lo anterior a Python:

Boost Python Export
#include <boost/python.hpp>

#define GENERATE_THE_CLASS_METHODS(classname)                                 \
    .def(                                                                     \
        "Foo",                                                                \
        ( void ( TheClass::* )( classname& ))( &TheClass::Foo ),              \
        ( boost::python::arg("arg") )                                         \
    )                                                                         \
    .def(                                                                     \
        "Bar",                                                                \
        ( void ( TheClass::* )( classname&, std::string ))( &TheClass::Bar ), \
        ( boost::python::arg("arg"), boost::python::arg("param") )            \
    )                                                                         \
    .def(                                                                     \
        "Bar",                                                                \
        ( void ( TheClass::* )( classname&, int ))( &TheClass::Bar ),         \
        ( boost::python::arg("arg"), boost::python::arg("param") )            \
    )

BOOST_PYTHON_MODULE(my_module)
{
    boost::python::class_< TheClass > ( "TheClass" )
        GENERATE_THE_CLASS_METHODS(SomeClass)
        GENERATE_THE_CLASS_METHODS(OtherClass)

        // This is the interesting part: all instantiations of the function
        // templates have to be inserted here. How can this be avoided
        // so that new classes can also be used?

    ;

    boost::python::class_< SomeClass > ( "SomeClass" );
    boost::python::class_< OtherClass > ( "OtherClass" );
}

(Pregunta secundaria: uso una macro aquí para evitar el código duplicado por razones de mantenimiento. ¿Hay alguna forma más hermosa de C ++ de lograr esto?)

Script de prueba de Python

El código anterior se compila usando Clang con C ++ 11, Boost 1.57.0 y Python 2.7.6. Funciona con este script de prueba:

#!/usr/bin/python

from my_module import *

s = SomeClass()
o = OtherClass()
t = TheClass()

t.Foo(s)
t.Foo(o)

t.Bar(s, 42)
t.Bar(o, 42)
t.Bar(s, "Hello World")
t.Bar(o, "Hello World")

Produciendo este outout:

Called Foo(SomeClass)
Called Foo(OtherClass)
Called Bar(SomeClass, 42)
Called Bar(OtherClass, 42)
Called Bar(SomeClass, Hello World)
Called Bar(OtherClass, Hello World)
Pregunta

En el ejemplo, las instancias de las plantillas de función para Foo () y Bar () se crean dentro de la definición de clase Boost :: Python (vea el comentario en el código fuente). Esto significa que un usuario de la biblioteca no puede agregar una nueva instanciación sin modificar este bit de código.

Por lo tanto, lo que estoy buscando es una forma de

"inyectar" esas instancias desde el exterior de la definición de clase Boost :: Pythonreabrir la definición de alguna maneraregistre las instancias necesarias en algún lugar antes de que se llame a la definición de clase Boost :: Python

Al final, un usuario de la biblioteca debería poder hacer algo como esto:

class AnotherClass
{
public:
    std::string Name()
    {
        return "AnotherClass";
    }
};

add_to_the_class(AnotherClass);
// or
add_to_class_definition<AnotherClass>("TheClass");
// or whatever works...

¿Es esto de alguna manera posible? ¿Hay otras formas de lograr algo similar?

Respuestas a la pregunta(1)

Su respuesta a la pregunta