undefined reference to `void sort::swap<int>(int*, int, int)' [duplicate]
Possible Duplicate:
Why can templates only be implemented in the header file?
Here's my make file:
#!/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) $开发者_StackOverflow社区(compiler_flags) -c sort.cpp
Here are my C++ Files:
// 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;
}
And, here's my problem:
./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
Any idea how to resolve this issue?
Template definitions need to either be visible at the point of use (so that they can be implicitly instantiated) OR you need to explicitly instantiate them (in this case the linker will bring the explicit instantiation and the usage together).
In your situation I would go with option one (and implicit instantiation). This means you need to move the template definition (of the template) into the header file:
// 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
Alternatively (but less useful in the general case (but has its uses)) is explicit template instantiation. Here you define in sort.cpp which variants of the template you want to have defined.
// 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);
}
This is useful when you want to limit the number of versions of a template are available.
Template definitions must be in the same file. So define the function in the header file itself.
Or include the .cpp
file in the header at the bottom as:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T> void swap(T*,int,int);
}
#include "sort.cpp" //<--------------- this!
#endif
You can not define templates in a .cpp
file. The definition of swap
should be in the sort.hpp
file only. See this FAQ Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file? for more details.
精彩评论