0

I have a problem with linking the following piece of code. Linker could not find the implementation of friend template function. Any idea why it could not find it?

Declaration

// XY.hpp
namespace xxx
{

template<typename T> class XY;

template<typename T>
std::ostream& operator<<(std::ostream&, const XY<T>&);

template<typename T>
class XY
{
public:
    // ... constructors, destructor, getters, setters, etc
    friend      std::ostream& operator<< <T>(std::ostream&, const XY<T>&);

private:
    //...

};

} /* namespace xxx*/

Definition

// XY.cpp
#include "XY.hpp"

namespace xxx
{

template<typename T>
std::ostream& operator<<(std::ostream& os, const XY<T>& rhs)
{
    // ...
    return os;
}
} /* namespace xxx */

Usage

// main.cpp
#include "XY.hpp"
#include <iostream>

using namespace std;
using namespace xxx;

int main() {
    XY<uint16_t> xy;
    cout << xy;

    return 0;
}

Linker returns error: undefined reference to 'std::ostream& xxx::operator<< <unsigned short>(std::ostream&, xxx::XY<unsigned short> const&)'

Linking with g++ -o "XXX" ./src/XY.o ./src/main.o
Version: gcc.EXE (GCC) 6.3.0

user3124812
  • 1,861
  • 3
  • 18
  • 39
  • [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) – Igor Tandetnik Apr 08 '17 at 18:17

1 Answers1

0

There is no operator<< definition when you define XY and use operator<<. You define a template in the source file, but there is no instantiation of this template for uint16_t. You can bypass via explicit template instantiation at the end of source file.

template std::ostream& operator<< <uint16_t> (std::ostream& os, const XY<uint16_t>& rhs);

But I think this is not a good idea. You'd better declare and define template in header file.

Bobo
  • 58
  • 8