c++ - Mensaje de error "referencia indefinida a la función de plantilla pasada como parámetro de plantilla"
templates inheritance (2)
Cuando paso una función de plantilla como un parámetro de plantilla de una clase base, el vinculador se queja de que no puede vincular la función:
#include <stdio.h>
template<int I> inline int identity() {return I;}
//template<> inline int identity<10>() {return 20;}
template<int (*fn)()>
class Base {
public:
int f() {
return fn();
}
};
template<int Val>
class Derived : public Base<identity<10> > {
public:
int f2() {
return f();
}
};
int main(int argc, char **argv) {
Derived<10> o;
printf("result: %d/n", o.f2());
return 0;
}
Resultados en:
$ g++ -o test2 test2.cpp && ./test2
/tmp/ccahIuzY.o: In function `Base<&(int identity<10>())>::f()'':
test2.cpp:(.text._ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv[_ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv]+0xd): undefined reference to `int identity<10>()''
collect2: error: ld returned 1 exit status
Si comento la especialización, el código se compila y enlaza como se espera. Además, si heredo de Base<identity<Val> >
lugar de Base<identity<10> >
, el código funciona como esperaba.
Pruebe aquí: http://coliru.stacked-crooked.com/a/9fd1c3aae847aaf7
¿Qué extraño?
Levantarlo en un typedef lo hace compilar, es decir
typedef Base< identity<10> > base10;
No estoy muy seguro de por qué hacerlo directamente en la definición de clase no funciona.
Parece que el problema es un error de gcc: el código se compila y enlaza con clang, icc y la interfaz EDG. Una solución alternativa potencial que no cambie ninguno de los usos sería el uso de una identity
plantilla de clase en lugar de una función:
template<int I>
struct identity {
operator int() { return I; }
};
template<typename fn>
class Base {
public:
int f() {
return fn();
}
};