C-callback a plantilla de función: instanciar explícitamente la plantilla

Premis

Estoy usando una biblioteca C (de C ++) que proporciona la siguiente interfaz:

void register_callback(void* f, void* data);
void invoke_callback();
Problem

Ahora, necesito registrar una plantilla de función como devolución de llamada y esto me está causando problemas. Considere el siguiente código:

template <typename T> void my_callback(void* data) { … }

int main() {
    int ft = 42;
    register_callback(reinterpret_cast<void*>(&my_callback<int>), &ft);
    invoke_callback();
}

Esto me da el siguiente error de enlazador (usando g ++ (GCC) 4.5.1 en OS Xbut funciona en la mayoría de las otras combinaciones de la versión / plataforma del compilador):

Símbolos indefinidos para arquitectura x86_64:

"void my_callback<int>(void*)", referenced from:  
  _main in ccYLXc5w.o

que me parece comprensible.

Primera "solución"

Esto se soluciona fácilmente creando una instancia explícita de la plantilla:

template void my_callback<int>(void* data);

Desafortunadamente, esto no es aplicable en mi código real ya que la devolución de llamada está registradadentr una plantilla de función, y no sé para qué conjunto de argumentos de plantilla se llamará esta función, por lo que no puedo proporcionar instancias explícitas para todos ellos (estoy programando una biblioteca). Entonces mi código real se parece un poco a esto:

template <typename T>
void do_register_callback(T& value) {
    register_callback(reinterpret_cast<void*>(my_callback<T>), &value);
    // Other things …
}

int main() {
    int ft = 42;
    do_register_callback(ft);
    invoke_callback();
}
Segunda "solución"

Una plantilla de función se instancia implícitamente llamando a la función. Así que hagamos eso, pero asegúrese de que la llamada no se realice realmente (la función tiene efectos secundarios):

template <typename T>
void do_register_callback(T& value) {
    if (false) { my_callback<T>(0); }
    register_callback(reinterpret_cast<void*>(my_callback<T>), &value);
}

Esta parece para trabajar, incluso con optimizaciones habilitadas (para que el compilador elimine la rama muerta). Pero no estoy seguro si esto no se romperá algún día. También encuentro que esta es una solución muy fea que requiere un comentario explicativo extenso para que algún futuro mantenedor elimine este código obviamente innecesario.

Pregunt

¿Cómo instanciar una plantilla para la que no conozco los argumentos de la plantilla? Esta pregunta obviamente no tiene sentido: no puedo. - ¿Pero hay una manera disimulada de esto?

Baring eso,Se garantiza que mi solución tenga éxito?

Pregunta extr

El código (específicamente, el hecho de que lanzo un puntero de función avoid*) también produce la siguiente advertencia:

ISO C ++ prohíbe la conversión entre puntero a función y puntero a objeto

cuando compila con-pedantic. ¿Puedo de alguna manera deshacerme de la advertencia,sin escribir un contenedor C fuertemente tipado para la biblioteca (que es imposible en mi situación)

Código de ejecución en ideone (con un reparto agregado para que se compile)

Respuestas a la pregunta(3)

Su respuesta a la pregunta