0

I have been stuck for a while now and am unable to figure out why I am getting this compile error.

Node.hpp

#ifndef H1
#define H1
template <typename T>
class Node{ 
  private: 
     T data;
  public:
     T getData();
};

#endif

Node.cpp

#include "Node.hpp"

template<typename T>
T Node<T>::getData(){
 return data;
}

main.cpp

#include <bits/stdc++.h>
#include "Node.hpp"
using namespace std;
int main()
{
 Node<int> *n = new Node<int>();
 cout << n->getData();
}

g++ main.cpp Node.cpp -std=c++17

O/P: main.cpp:(.text+0x24): undefined reference to `Node::getData()'collect2: error: ld returned 1 exit status

PS: I tried the same thing without any template (use a primitive datatype instead), I do not get any error. So this probably has got something to do with the typename. Would be great if someone could tell me what is wrong here.

harsh
  • 63
  • 5
  • The compiler can't see getData from Node.cpp when compiling main.cpp so can't instantiate the templte (or at least can't properly instantiate all of it). You'll need to put getData in Node.hpp – systemcpro Mar 27 '21 at 09:55
  • Yes, I have declared getData() in Node.hpp. – harsh Mar 27 '21 at 09:59
  • Also, the code works perfectly fine if I replace template by int, which probably means visibility is not a problem.. – harsh Mar 27 '21 at 10:00
  • It is declared but not defined in Node.hpp. You will also need to define it in Node.hpp too otherwise the compiler can't see it in main.cpp – systemcpro Mar 27 '21 at 10:01
  • Okay defining in Node.hpp worked. – harsh Mar 27 '21 at 10:07
  • But I am supposed to define my functions in Node.cpp only. Moreover, I am passing Node.cpp while compiling, so why is the definition not visible? – harsh Mar 27 '21 at 10:08
  • An why is it visible when I use int instead? – harsh Mar 27 '21 at 10:08
  • See https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – systemcpro Mar 27 '21 at 10:09
  • [Why should I not #include ?](https://stackoverflow.com/q/31816095) – prapin Mar 27 '21 at 12:26

1 Answers1

0

Node.hpp

#ifndef H1
#define H1
template <typename T>
class Node{ 
private: 
    T data;
 public:
    T getData() { return data; }
};

//or define it here

#endif

Then no need for Node.cpp. You might want to consider returning a const reference if your use-case allows it as T now requires a copy constructor. Although maybe that's what you want, I don't know your use-case.

See Why can template only be defined in header files

systemcpro
  • 744
  • 1
  • 6
  • 13