3

I'm referencing a templated quicksort method in my cpp function like this:

Main.cpp

QuickSort<vector<int>>(testData);

Where testData is:

int arr[] = {0, 5, 3, 4, 2, 1, 4};
vector<int> testData (arr, arr + sizeof(arr) / sizeof(arr[0]));

The declaration of quicksort in the .h file is:

Sorting.h

template <typename T>
void QuickSort(std::vector<T>& Unsorted);

And the function definition is:

Sorting.cpp

template <typename T>
void QuickSort(std::vector<T>& Unsorted) 
{
         //implementation here
}

Am I losing my mind? I'm just trying to pass a vector of ints by reference. Could someone tell me where I'm going wrong?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Darkenor
  • 4,349
  • 8
  • 40
  • 67
  • 1
    May it be because of the shift-operator in `QuickSort>`? That's a problem with anything before C++0x, see [here](http://stackoverflow.com/questions/5771131/nested-templates-vs-shift-operator) – Joost Jul 22 '12 at 19:35
  • @Joost that issue would occur after moving impl to one place, but most of modern compilers aleady distinguish between bitshift and nested templates – Bartosz Przybylski Jul 22 '12 at 19:43

1 Answers1

4

templates cannot have separate definition and declaration

also

QuickSort<int>(vec);

in case of functions declaration and definition must be in the saem place, ie:

#include <vector>

template <typename T>
void qs(std::vector<T>&v );

int main() {
  std::vector<int> v;
  qs(v);
}


void qs(std::vector<T>&v ) { 
}

wont compile, when

#include <vector>

template <typename T>
void qs(std::vector<T>&v ) {}

int main() {
  std::vector<int> v;
  qs(v);
}

compiles just fine, check in stl how template functions are made. The thing is, that compiler must know entire function before its usage, and he doesnt in your case

Bartosz Przybylski
  • 1,628
  • 10
  • 15
  • That's a different error message. Here it is the compiler reporting but not the linker. – Mahesh Jul 22 '12 at 19:26
  • -1: Yes they can. The definition generally can't go in a .cpp file, but they *can* be separate – Nicol Bolas Jul 22 '12 at 19:26
  • author doesnt stand that def is in hpp, also check edit, for correct call – Bartosz Przybylski Jul 22 '12 at 19:27
  • Thanks - calling the function wrong. Oy. I hate mistakes like that. – Darkenor Jul 22 '12 at 19:37
  • Also - Bartek, why can't you put the definition of a templated function into a cpp file? Seems rather silly to keep them in a header file? – Darkenor Jul 22 '12 at 19:40
  • It's a language specification, compiler must know entire function definition. Template functions are generated while compiling and generic func, cannot be put into cpp file, altho, template specialization can. – Bartosz Przybylski Jul 22 '12 at 19:42
  • @Bartek: They're still wrong. The reason the first example didn't compile is because the definitions are *different*. The second one is not a template. See this [Ideaone example](http://ideone.com/vp6mg). – Nicol Bolas Jul 22 '12 at 19:43
  • @NicolBolas in that example, yes it would compile, but including generic template declaration without its definition its incorrect. And even if its definition was in other cpp file it wasnt template specialization (which compiler was looking for in that case). since there was no specialization and no generic template in header file, for own specialization creation, that caused linking error. – Bartosz Przybylski Jul 22 '12 at 21:47
  • @Bartek: Yes, you need both. But they don't have to be in the same place; you just need to include both of them. Therefore, the statement "templates cannot have separate definition and declaration" is *incorrect*. – Nicol Bolas Jul 22 '12 at 21:48
  • ok, it was not precise enough, it shoudl be more like: definition needs to be accessible when before linking phase (so compiler could specialize func by himself), but including cpp files is just so wrong ;) – Bartosz Przybylski Jul 22 '12 at 21:52