2

I'm currently writing a logger for my C++ project (I need it to have near to no dependences, so I don't want to take a prewritten one). It contains this function:

template <typename T>
Logger& Logger::operator<<(T f) {
  m_file<<f;
  return *this;
}

The logger.cpp code compiles, but when I call the log functions in my main.cpp, I have this compiler error:

/home/tuxer/prog/cpp/PRay/server/src/main.cpp:110: undefined reference to `Logger& Logger::operator<< <int>(int)'

for this line of code :

log<<lul; (lul being a int variable equals to 2)

The logger.o file is correctly included, as the Logger::init() function works properly and doesn't raise any linking error. Thanks :)

Tuxer
  • 753
  • 1
  • 6
  • 20

2 Answers2

3

Since you have non-inline templates, you need to force instantiation. See for example How do I force a particular instance of a C++ template to instantiate?.

Community
  • 1
  • 1
smparkes
  • 13,807
  • 4
  • 36
  • 61
2

The simple thing to do is to put the Logger::operator<< template in the header file. The compiler will automatically instantiate the versions it needs, and the linker will remove the duplicates (well, at least the ones that weren't inlined).

You shouldn't need to force instantiation unless your linker is old (e.g. gcc 2.7 or earlier).

This is the general rule with template code: put the definitions in the header file unless you have a good reason not to.

See Why can templates only be implemented in the header file? as well.

Community
  • 1
  • 1
Mike DeSimone
  • 41,631
  • 10
  • 72
  • 96