0

It's the first time that I try to use templates in my functions but I can't seem to make them work. I defined my function in a file called ddc.hpp

#ifndef __DIGITAL_DOWN_CONVERTER_H__
#define __DIGITAL_DOWN_CONVERTER_H__
namespace ddc {
    template <class T> void perform_resampling(std::vector<T> &, unsigned int, unsigned int);
}
#endif

and implemented it in ddc.cpp

#include "ddc.hpp"
template <class T>
void ddc::perform_resampling(std::vector<T> &data, unsigned int f1, unsigned int f2) {
    // do stuff
}

and here's my main.cpp

#include "ddc.hpp"
int main() {
    std::vector<float> v (100000);
    ddc::perform_resampling(v, 1000, 10);

    return 0;
}

Compiling with gcc (linux) I get the following error:

$ g++ -c ddc.cpp -o ddc.o -Wall -O3 -lm -m64
$ g++ -c main.cpp -o main.o -Wall -O3 -lm -m64
$ g++ ddc.o main.o -o ../bin/resampler

main.o: In function `main':
main.cpp:(.text.startup+0xed): undefined reference to `void ddc::perform_resampling<float>(std::vector<float, std::allocator<float> >&, unsigned int, unsigned int)'
collect2: ld returned 1 exit status
make: *** [../bin/HW_3] Error 1

Am I doing something wrong?

mr_hyde
  • 505
  • 1
  • 6
  • 11
  • you can't separate the interface from the definition like you do with functions and methods, it's simple as that, you need to declare and define a template all in one place, the reasons are clear if you are willing to read something about templates, but in short your first block of code doesn't make sense for the compiler and it's lacking the template definition. – user2384250 May 26 '13 at 14:43

3 Answers3

2

Template definitions need to go with declarations, so everything needs to be in the header file.

user123
  • 8,970
  • 2
  • 31
  • 52
1

You need to put your template implementation in the header too.

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
1

You need to place the definition of the template function in a location that is visible to the code that uses it or use explicit template instantiation to ensure the code for the function is generated.

If you do not want to expose the implemention of perform_resampling you can still force the the compiler to explicitly generate the code for it. The following line when placed in ddc.cpp will instruct the compiler to generate code for perform_resampling taking a vector<float> as it's first parameter.

template void ddc::perform_resampling(std::vector<float> &data, unsigned int f1, unsigned int f2);
Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74