0

So I had an problem with partial specialization of function templates. I choose the solution described here: Question

Now I have this:

#include <vector>
#include <iostream>

template <typename T> struct helper {
    static void print(T value) { std::cout << value; }
};
template <typename T> struct helper<std::vector<T>> {
    static void print(std::vector<T> const &value) { }
};

template <typename T>
void print (T const &value) {
    // Just delegate.
    helper<T>::print (value);
}


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

But I want to have this layout:

helper.hpp

#include <vector>
#include <iostream>

template <typename T> struct helper {
    static void print(T value) { std::cout << value; }
};

vector_helper.cpp

#include <vector>
#include <iostream>

template <typename T> struct helper<std::vector<T>> {
    static void print(std::vector<T> const &value) { }
};

print.hpp

#include "helper.hpp"

template <typename T>
void print (T const &value) {
    // Just delegate.
    helper<T>::print (value);
}

main.cpp

#include "print.hpp"

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

Compiled like this:

g++ main.cpp vector_helper.cpp

The problem is that MinGW is producing linking-time erros: undefined reference to helper<vector<...>>::print(vector<...>)

When I add the line:

#include "vector_helper.cpp"

before int main() {...}, it compiles fine and also works. How can I solve it, because I want to add the class specialization in the file linked by the g++ command.

Community
  • 1
  • 1
Tim
  • 5,521
  • 8
  • 36
  • 69

1 Answers1

0

Those template classes can't be split into separate object files and remain wholly unspecialised. If you look at the standard templates like vector, you'll see that everything is in a single headerfile for this reason.

If you want to hide the implementation of your templates like that, you have to force instantiation of them to one or more specific types. You might do this by sticking something like

template class helper<std::vector<int>>;

at the end of vector_helper.cpp, if I recall correctly. But you're best off keeping all your templates in headers.

Rook
  • 5,734
  • 3
  • 34
  • 43
  • Mind you, I can't get the code to compile even if I try to force instantiation under GCC... but then, I'm not really familiar with the right ways to do the wrong things! – Rook Nov 08 '12 at 18:52
  • Thank you for your clear answer, I'm not looking to do wrong things right. But I quess that including template specializations as spliced header files would be legal c++? – Tim Nov 08 '12 at 19:23
  • @Tim I believe so, yes. I believe that the next revision of the C++ standard is likely to contain slightly better support for spreading templates across compile units, but in the mean time your life is likely to be much easier if you just stick to definitions in header files. – Rook Nov 09 '12 at 10:51