1

I tried to overload the ostream << operator to print out a generic-typed variable, however main.cpp can not find the implementation. I am assuming that this is because the implementations exists in a .cpp file. I am aware that template functions must usually be defined in the header files, however this should not be the case for explicitly-instantiated functions. When I copy the implementation into my header file, it works just fine.

I'm thinking that I'm experiencing an issue that is unique to templated friend functions. Here are the relevant parts of my code.

I forward declared my Node class and the operator overload

template <typename T> class Node;
template <typename T> ostream& operator<< (ostream&, Node<T>&);

I declared the operator overload in my header file (Tree.h)

template <typename T>
class Node
{
  ...
    friend ostream& operator<< <T> (ostream&, Node<T>&);
    T data;
  ...
}

in my .cpp file, I implemented it

#include "Tree.h"
template <typename T>
ostream& operator<< (ostream& out, Node<T>& node)
{
    out << node.data;
    return out;
}

I explicitly instantiated my Node at the bottom of my Tree.cpp file

template class Node<int>;

then finally I called it from main.cpp

int main()
{
    Node<int>* n0 = new Node<int>(0);
    cout << (*n0);
}

and I get the following error:

undefined reference to 'std::ostream& operator<< <int> (std::ostream&, Node<int>&)'
  • Template functions, whether `friend` or otherwise, generally [must be implemented in a header file](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Igor Tandetnik Nov 16 '17 at 04:35
  • Not a duplicate. All the other questions don't answer why the main.cpp won't recognize my function. My function is explicitly instantiated, and the main.cpp still won't recognize the function. – Anthony Yershov Nov 16 '17 at 04:38
  • The top answer to the question I linked does: "Consequently, the compiler needs to have access to the implementation of the methods, to instantiate them with the template argument (in this case int). If these implementations were not in the header, they wouldn't be accessible, and therefore the compiler wouldn't be able to instantiate the template." And then linker cannot find the instantiation that the compiler was unable to provide, and complains. – Igor Tandetnik Nov 16 '17 at 04:41
  • I have plenty of methods in my cpp file, which are all recognized. only the friend function is not recognized. I've edited my question to show the explicit instantiation. – Anthony Yershov Nov 16 '17 at 04:43
  • 1
    That explicitly instantiates `Node` and its members. But your `operator<<` is not a member of `Node`. You can explicitly instantiate it, too, if you are so inclined: `template ostream& operator<< (ostream&, Node&);` – Igor Tandetnik Nov 16 '17 at 04:47
  • Thank you for your help Igor. – Anthony Yershov Nov 16 '17 at 04:48

0 Answers0