9

I have a C++ class that is declared and implemented in a header file. I chose this because one cannot easily move between Debug and Release builds due to _GLIBCXX_DEBUG and precompiled libraries. For example, if I define _GLIBCXX_DEBUG, Boost will crash due to ABI changes in the source files.

The header only implementation has created a problem with duplicate symbols. For example, in the class below operator== and non-member swap will produce multiply defined symbols.

// Foo.hpp
namespace Bar
{
  template
  class Foo
  {
    ...
  };

  bool operator==(const Foo& a, const Foo& b) {
    ..
  }
}

namespace std
{
  template <>
  void swap(Bar::Foo& a, Bar::Foo& b)
  {
    a.swap(b);
  }
}

When declaration and implementation were split, the files (Foo.hpp and Foo.cpp) compiled and linked OK.

What is the trick to get this to compile and link properly?

Flexo
  • 87,323
  • 22
  • 191
  • 272
jww
  • 97,681
  • 90
  • 411
  • 885

1 Answers1

11
inline bool operator==(const Foo& a, const Foo& b) {
    ..
  }

Member functions are implicit inline provided they are defined inside their class. The same stuff is true for them true: If they can be put into the header without hassle, you can indeed do so.

Because the code of the function is put into the header and visible, the compiler is able to inline calls to them, that is, putting code of the function directly at the call site (not so much because you put inline before it, but more because the compiler decides that way, though. Putting inline only is a hint to the compiler regarding that). That can result in a performance improvement, because the compiler now sees where arguments match variables local to the function, and where argument doesn't alias each other - and last but not least, function frame allocation isn't needed anymore.

Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177
  • Perfect, thanks. I tried to pound in `static` rather than `inline` – jww Nov 19 '12 at 04:15
  • 4
    Man, I just landed on my own question three years later... Now I have a data member in a header-only implemenation causing the same error. The data member is `static`, and its initialized in the header (but outside the class declaration) because there's no implementation file. How do I work around that one (or should I ask a new question). – jww Sep 27 '15 at 14:38
  • 2
    Found it at [How to have static data members in a header-only library?](http://stackoverflow.com/q/11709859). Some of these silly C++ language rules are maddening at times... – jww Sep 27 '15 at 14:54
  • Thanks. Adding explicit inline solved my problem, too. – kakyo Oct 22 '19 at 07:23