1

I have a class graph.h written like this

#include <fstream>
using namespace std;

template <typename T>
class Graph
{
private:
    T ** graphData;
public:
    Graph(ifstream & inputFile);
    ~Graph(){};
    friend ofstream & operator<<(ostream&, const Graph &);
};

where constructor Graph(ifstream & inputFile); is defined in graph.cpp:

#include "graph.h"  
template <typename T>
Graph<T>::Graph(ifstream & inputFile){}

I tried to make an instance of this class in main.cpp:

#include <fstream>
#include "graph.h"    
using namespace std;

int main()
{
    ifstream myFile ("example.txt");
    Graph<int> * IntGraph = new Graph<int>(myFile);
    return 0;
}

but I keep getting these errors

Error   1   error LNK2019: unresolved external symbol "public: __thiscall Graph<int>::Graph<int>(class std::basic_ifstream<char,struct std::char_traits<char> > &)" (??0?$Graph@H@@QAE@AAV?$basic_ifstream@DU?$char_traits@D@std@@@std@@@Z) referenced in function _main    C:\Users\Vlada\Dropbox\FJFI\BP - Graph partitioning\BP-program\BP-program\main.obj  BP-program
Error   2   error LNK1120: 1 unresolved externals   C:\Users\Vlada\Dropbox\FJFI\BP - Graph partitioning\BP-program\Debug\BP-program.exe BP-program

I tried to search, but none of the result I found seemed to me like this.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
P.Brown
  • 11
  • 1
  • 6
  • 1
    Define member functions in the header. The compiler needs to see the template function definitions. – Vlad from Moscow Mar 02 '16 at 19:27
  • So it is imposible to define the functions outside the class, when writing a template? – P.Brown Mar 02 '16 at 19:34
  • There was an attempt to do that but in the new C++ Standard it is impossible. – Vlad from Moscow Mar 02 '16 at 19:37
  • That's an FAQ actually, check out the C++ FAQ at parashift's. – Ulrich Eckhardt Mar 02 '16 at 19:38
  • templated class methods can be defined outside the class, but they still have to be defined where anyone using the method can include and see them. In other words in a header. End result is you don't gain much by separating them from the class. Details and effectively a dupe here: [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – user4581301 Mar 02 '16 at 19:42
  • Thank you all for the solution! – P.Brown Mar 02 '16 at 19:46

2 Answers2

3

Each compilation unit that refers to member functions of a template class needs to see the function definitions.

So move the constructor definition from the cpp module to the header.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
-1

Use the following include statement after your declaration of graph.h. This way the implementation is still separated from the definition, and the compiler can access it.

#include "graph.cpp"

A template is not a class or a function. A template is basically a generalized pattern which helps the compiler to generate a particular type of requested class or a function.

In order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to “fill in” the template. For example, if you’re trying to use a Graph, the compiler must see both the Graph template and the fact that you’re trying to make a specific Graph.

Your compiler probably doesn’t remember the details of one .cpp file while it is compiling another .cpp file. This is called the “separate compilation model.”

References :

  1. https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
  2. Why can templates only be implemented in the header file?
Community
  • 1
  • 1
Luv
  • 44
  • 6