可能重复:
Why can templates only be implemented in the header file?
这是我的make文件:
#!/usr/bin/make -f
compiler = g++
compiler_flags = -Wall -I /usr/include/c++/4.5
debug_flags = -D DEBUG -g
binary_filename = sort_testing.bin
all: clean release
release:
$(compiler) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
debug: sort.o
$(compiler) $(debug_flags) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
run:
./$(binary_filename)
clean:
rm -f *.o $(binary_filename)
sort.o:
$(compiler) $(debug_flags) $(compiler_flags) -c sort.cpp
以下是我的C ++文件:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T> void swap(T*,int,int);
}
#endif
// sort.cpp
#include "sort.hpp"
namespace sort{
template<class T>
void swap(T* items, int index_a, int index_b){
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
}
// main.cpp
#include <iostream>
#include <exception>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#include "sort.hpp"
using namespace sort;
#define NUM_INTS 5
int main(int argc, char** argv){
try{
cout << "\n\n\n";
srand(time(NULL));
int * int_coll = new int[NUM_INTS];
for (int x = 0; x < NUM_INTS; x++)
int_coll[x] = rand() % 100 + 1;
cout << "Before swap" << endl;
for (int x = 0; x < NUM_INTS; x++)
cout << "int " << x << " == " << int_coll[x] << endl;
cout << "\n\n\n";
cout << "Swapping ints" << endl;
swap<int>(int_coll, 0, 1);
cout << "AFter swap" << endl;
for (int x = 0; x < NUM_INTS; x++)
cout << "int " << x << " == " << int_coll[x] << endl;
}catch(exception& e){
cout << "Exception: " << e.what() << endl;
}
return 0;
}
而且,这是我的问题:
./make clean debug
rm -f *.o sort_testing.bin
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 -c sort.cpp
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 main.cpp sort.o -o sort_testing.bin
/tmp/ccRl2ZvH.o: In function `main':
/home/dev/c++/sorting/main.cpp:33: undefined reference to `void sort::swap<int>;(int*, int, int)'
collect2: ld returned 1 exit status
make: *** [debug] Error 1
知道如何解决此问题吗?
答案 0 :(得分:1)
模板定义需要在使用点可见(以便可以隐式实例化) OR 您需要显式实例化它们(在这种情况下,链接器将带来显式实例化和一起使用)。
在你的情况下,我会选择一个(和隐式实例化)。这意味着您需要将(模板的)模板定义移动到头文件中:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T>
void swap(T*,int,int)
{
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
}
#endif
或者(但在一般情况下不太有用(但有其用途))是显式模板实例化。在这里,您可以在sort.cpp中定义要定义的模板的哪些变体。
// sort.cpp
#include "sort.hpp"
namespace sort{
template<class T>
void swap(T* items, int index_a, int index_b){
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
// Define an explicit function template instantiation.
// Here we define that the integer version of the template must exist.
template void swap<int>(int*,int,int);
}
当您想限制模板的版本数量时,这非常有用。
答案 1 :(得分:0)
模板定义必须位于同一文件中。因此,在头文件本身中定义函数。
或者将.cpp
文件包含在底部的标题中:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T> void swap(T*,int,int);
}
#include "sort.cpp" //<--------------- this!
#endif
答案 2 :(得分:0)
您无法在.cpp
文件中定义模板。 swap
的定义应仅在sort.hpp
文件中。有关详细信息,请参阅此常见问题解答Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?。