Kiedy używam specjalistycznego szablonu w różnych plikach obiektowych, podczas łączenia pojawia się błąd „wielokrotnej definicji”. Jedyne rozwiązanie, które znalazłem, polega na użyciu funkcji „inline”, ale wydaje się, że jest to jakieś obejście. Jak rozwiązać ten problem bez użycia słowa kluczowego „inline”? Jeśli to niemożliwe, dlaczego?
Oto przykładowy kod:
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
Wreszcie:
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
Jeśli odkomentuję „inline” wewnątrz hello.h, kod skompiluje się i uruchomi, ale wydaje mi się to pewnym „obejściem”: co jeśli wyspecjalizowana funkcja jest duża i używana wiele razy? Czy dostanę duży plik binarny? Czy jest inny sposób, aby to zrobić? Jeśli tak, w jaki sposób? Jeśli nie, dlaczego?
Próbowałem poszukać odpowiedzi, ale wszystko, co otrzymałem, to „użyj inline” bez dalszych wyjaśnień.
Dzięki