0

So here is a question I could not get an answer to, even after searching this website (and others) for the last two days.

For the sake of argument, lets assume that I wanted to create two template classes a and b. Class a is just a user defined datatype, say a vector or matrix, so I can overload different operators and make working with these special datatype easier. Class b is going to take class a as a template parameter (which can be thought of a 2D field of vectors or whatever datatype a represents) and both class a and b should be declared in a header file but implemented in a .cpp file.

EDIT: I am aware what that templates are limited, in the sense that we have to implement them in header files. But I am also aware that we can define explicit template argument at compile time (if we know which template arguments will be taken) and then split the implementation into header and .cpp files. This works fine if my template arguments are standard c++ types such as float, doubles or int but I don't know how to proceed when the template argument is a class with template parameters itself, see the following code with explanations.

In code form, this would loke something like this

a.h

template<class T>
class a {
    public:
        a(T);
    private:
        T data;
};

a.cpp

#include <iostream>
#include "a.h"

// explicit template declaration
template class a<double>;

template<class T>
a<T>::a(T in) {
    data = in;
}

b.h

template< class T>
class b {
    public:
        b(T);
    private:
        T item;
};

b.cpp

#include <iostream>
#include "b.h"

// explicit template template declaration
template class b<double>;

template<class T>
b<T>::b(T in) {
    item = in;
}

and finally main.cpp

#include <iostream>
#include "a.h"
#include "b.h"

int main() {
    a<double>    foo(3);   // this works
    b<a<double>> bar(foo); // this doesn't
    return 0;
}

when I compile and run the above I get

main.cpp:7: undefined reference to `b<a<double> >::b(a<double>)' 

I have been tinkering with the code for a while, I know the issue is with the b class. I have tried using

template<template<class> class T>

instead of

template<class T>

which I think should be the correct usage (or in a similar form) but then I am getting issues with the explicit template declaration in the b.cpp file and this is only as far as my template understanding goes.

Any ideas which changes should be made to b.cpp and b.h to make this minimal example work?

tom
  • 361
  • 3
  • 11
  • I am not sure why this has been marked as duplicate, the suggested post [link](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) is related but not answering my problem. If you look at my a.h and a.cpp file, you will see that I am already declaring my templates explicitly so I don't get a compilation error (see also the main.cpp file where it is indicated that this is working). My problem is with using a template class as a template argument in another class, i.e. using class a as a template argument in class b (again, indicated in main.cpp). – tom Aug 06 '18 at 06:17
  • No, you can't put `b::b` in a separate translation unit from places that use it. It's not a compiler error, but a linker error – Caleth Aug 06 '18 at 08:14
  • Aren't you just missing `template class b>;`? – Quentin Aug 06 '18 at 09:00
  • @Quentin cheers, that solved the problem ... seems so obvious but i was apparently looking in a different area (template template arguments), didn't realise the solution was that simple, thanks again! – tom Aug 06 '18 at 12:48

0 Answers0