Эта проблема заключается в определении и объявлении шаблона функции в пространстве имен, которое определено во внешнем файле, из которого создается функция. Вот самый маленький воспроизводимый пример, который я мог придумать. Далее следуют 4 файла:
Объявление шаблона функции в именованном пространстве имен:
// bar.h
#include <algorithm>
namespace barspace {
template <typename Iter>
void DoSomething (Iter first, Iter last);
}
Определение шаблона функции в отдельном файле:
// bar.cpp
#include "bar.h"
namespace barspace {
template <typename Iter>
void DoSomething (Iter first, Iter last) {
typedef typename std::iterator_traits<Iter>::value_type val_t;
std::sort (first, last);
}
} // namespace barspace
Заголовок для основной программы
// foo.h
#include "bar.h"
#include <vector>
Наконец, основная программа, в которой вызывается шаблон функции:
//foo.cpp
#include "foo.h"
int main () {
std::vector<double> v_d;
for (int i = 0; i < 10; i++) {
v_d.push_back (i);
}
barspace::DoSomething (v_d.begin(), v_d.end());
return 0;
}
Я компилирую следующим образом:
g++ -c -o bar.o bar.cpp
g++ -c -o foo.o foo.cpp
Они работают нормально. Теперь для ссылки:
g++ bar.o foo.o -o foobar
И полученная ошибка компилятора о неопределенной ссылке:
foo.o: In function `main':
foo.cpp:(.text+0x6e): undefined reference to `void barspace::DoSomething<__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > > >(__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >)'
collect2: ld returned 1 exit status
Существует очевидная проблема с кодом, который не становится доступным из namespace
или из модуля компиляции bar
.
Кроме того, когда я пытаюсь поместить определение DoSomething
в заголовок bar.h
, как я хотел бы обойти проблемы при определении методов шаблона класса в отдельных файлах .cpp, я получаю ту же ошибку.
Можете ли вы пролить свет на ошибку компиляции моего компилятора?