Cuando utilizo una plantilla especializada en diferentes archivos de objeto, obtengo un error de "definición múltiple" al vincular. La única solución que encontré implica el uso de la función "en línea", pero parece una solución alternativa. ¿Cómo soluciono eso sin usar la palabra clave "en línea"? Si eso no es posible, ¿por qué?
Aquí está el código de ejemplo:
paulo@aeris:~/teste/cpp/redef$ cat hello.h
#ifndef TEMPLATE_H
#define TEMPLATE_H
#include <iostream>
template <class T>
class Hello
{
public:
void print_hello(T var);
};
template <class T>
void Hello<T>::print_hello(T var)
{
std::cout << "Hello generic function " << var << "\n";
}
template <> //inline
void Hello<int>::print_hello(int var)
{
std::cout << "Hello specialized function " << var << "\n";
}
#endif
paulo@aeris:~/teste/cpp/redef$ cat other.h
#include <iostream>
void other_func();
paulo@aeris:~/teste/cpp/redef$ cat other.c
#include "other.h"
#include "hello.h"
void other_func()
{
Hello<char> hc;
Hello<int> hi;
hc.print_hello('a');
hi.print_hello(1);
}
paulo@aeris:~/teste/cpp/redef$ cat main.c
#include "hello.h"
#include "other.h"
int main()
{
Hello<char> hc;
Hello<int> hi;
hc.print_hello('a');
hi.print_hello(1);
other_func();
return 0;
}
paulo@aeris:~/teste/cpp/redef$ cat Makefile
all:
g++ -c other.c -o other.o -Wall -Wextra
g++ main.c other.o -o main -Wall -Wextra
Finalmente:
paulo@aeris:~/teste/cpp/redef$ make
g++ -c other.c -o other.o -Wall -Wextra
g++ main.c other.o -o main -Wall -Wextra
other.o: In function `Hello<int>::print_hello(int)':
other.c:(.text+0x0): multiple definition of `Hello<int>::print_hello(int)'
/tmp/cc0dZS9l.o:main.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status
make: ** [all] Erro 1
Si elimino el comentario "en línea" dentro de hello.h, el código se compilará y se ejecutará, pero eso me parece una especie de "solución": ¿qué pasa si la función especializada es grande y se usa muchas veces? ¿Obtendré un binario grande? Hay alguna otra manera de hacer esto? Si es así, ¿cómo? Si no, ¿por qué?
Traté de buscar respuestas, pero todo lo que obtuve fue "usar en línea" sin más explicaciones.
Gracias