-2

I tried to make a template class for an implementation of a 3D vector. Relevant snippet of the 2 files (vec3d.h and vec3d.cpp) are here on pastebin.

The main.cpp is as follows:

#include "vec3d.h"

#include <iostream>

using namespace std;

int main()
{
    Vec3D<double> a(1,2,3), b(2,4,5), c;
    c = 2.3*b;
    cout<<c._x;
   return 0;
}

On compiling it with g++ main.cpp vec3d.cpp vec3d.h the following error occurs:

In function `main':
main.cpp:(.text+0x124): undefined reference to `Vec3D<double> const operator*<double>(double, Vec3D<double> const&)'
collect2: error: ld returned 1 exit status

I have put the definition and declarations of the functions separately, but I have also instantiated the template for double.

Funnily enough, c = b*2.3 does not throw an error. Any reasons? I am also getting the same error on several other functions (like <<, ==, / all are declared in similar fashion)

What am I doing wrong?

[[EDIT]]

I instantiated the class, as should be, but I didn't instantiated the template functions which are present outside of the class. Apparently, I have to instantiate the too. Didn't know that.

More: Refer to this question. Every C++ unit defined using a template has to be instantiated if the definitions are in a separate file from the file with declarations, not just classes

Community
  • 1
  • 1
Kunal Tyagi
  • 549
  • 4
  • 12
  • You should show us the class `Vec3D` along with its explicit instantiations. – David G Oct 10 '14 at 19:59
  • @πάντα ῥεῖ "I have put the definition and declarations of the functions separately, but I have also instantiated the template for double" - I think he's aware of the problem of separating the declaration and definition, but he said he instantiated the template for double. I think that since the error shows that `operator*` is a function template, he's explicitly instantiated the *member function* `operator*` but not the *global one* (the one that takes a double on the left hand side as shown in the error). – David G Oct 10 '14 at 20:05
  • Did you remember to explicitly instantiate the global operator function? `template Vec3D const operator*(double, Vec3D const&)` – David G Oct 10 '14 at 20:16
  • You should implement the entire template class and operators in the header, why instantiate the template in the cpp for a single type? The operators required are not instantiated as you have it. – Niall Oct 10 '14 at 20:28
  • @0x499602D2 Looks like the OP themselves accepts, that the dupe answers their question. Looks like I've used the dupe hammer to close, you reopened, and then it was closed as the same dupe again, right? – πάντα ῥεῖ Oct 11 '14 at 17:38
  • @πάνταῥεῖ Yeah but I never reopened it after you closed, I guess someone else did. – David G Oct 11 '14 at 17:43

1 Answers1

1

The operators required are not instantiated as you have it (despite the class' instantiation), they are not members of the class. Hence they are declared but the definition is not found.

You should implement the entire template class and associated operators in the header.

Niall
  • 30,036
  • 10
  • 99
  • 142