Optional header only library
Asked Answered
K

1

8

I'd like to write a C++ library which is not-header-only by default but could be used as a header only library defining a NOLIB macro.

I've seen two approaches:

  • inline definitions

foo.h

#if !defined(FOO_H)
#define      FOO_H

#if defined(NOLIB)
#  define MYINLINE inline
#else 
#  define MYINLINE 
#endif

class foo
{
  // ...
};

#if defined(NOLIB)
#  include "foo.cc"
#endif

#endif  // include guard

foo.cc

#if !defined(NOLIB)
#  include "foo.h"
#endif

MYINLINE void foo::something() { ... }

  • "Artificial" template

foo.h

#if !defined(FOO_H)
#define      FOO_H

#if defined(NOLIB)
#  define MYTEMPLATE template<bool DUMMY>
#  define MYFOO      foo_impl
#  define MYFOO_T    foo_impl<DUMMY>
#else
#  define MYTEMPLATE
#  define MYFOO      foo
#  define MYFOO_T    foo
#endif

MYTEMPLATE
class MYFOO
{
  // ...
};

#if defined(NOLIB)
   using foo = foo_impl<true>;
#  include "foo.cc"
#endif

#endif  // include guard

foo.cc

#if !defined(NOLIB)
#  include "foo.h"
#endif

MYTEMPLATE
void MYFOO_T::something() { ... }

What are the pros and cons of these approaches? Are there better options?

Katowice answered 24/4, 2014 at 13:1 Comment(1)
If the functions are small enough to be inlined, you could potentially ship the implementations in a static library, or even ship the .cc files.Storey
T
2

There is no real difference in each approach because both inline methods or templates could end up be inserted inline with your code depending on compiler optimizations. See this post discussing inline vs templates.

Tshombe answered 25/4, 2014 at 2:41 Comment(2)
I‘m not too worried of code bloat one reason being that header-only version would be for casual user. I was thinking of problems like circular dependency or other unforeseen issues that may emerge trying to convert a standard library. Also the artificial template seems a stretch of C++ language.Katowice
I think the main thing to watch for in either case is to avoid having a using namespace line in your code which could cause problems for the end user, so you should implement everything within a namespace (if you are suing them). You could have circular dependencies in either of the cases you mentioned.Tshombe

© 2022 - 2024 — McMap. All rights reserved.