2014-04-24 13 views
6

Ich würde gerne eine C++ - Bibliothek schreiben, die nicht-Header-only standardmäßig ist, aber könnte als eine Header-Bibliothek verwendet werden, die eine NOLIB Makro definieren.Optionale Header nur Bibliothek

Inline-Definitionen

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

0123:

ich zwei Ansätze gesehen haben

#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() { ... } 

Was sind die Vor- und Nachteile dieser Ansätze? Gibt es bessere Möglichkeiten?

+0

Wenn die Funktionen klein genug sind, um inline zu sein, können Sie die Implementierungen möglicherweise in einer statischen Bibliothek bereitstellen oder sogar die .cc-Dateien versenden. –

Antwort

2

Es gibt keinen wirklichen Unterschied in jedem Ansatz, da beide Inline-Methoden oder Vorlagen in Abhängigkeit von Compiler-Optimierungen inline mit Ihrem Code eingefügt werden könnten. Siehe this Beitrag diskutieren inline vs Vorlagen.

+0

Ich bin nicht allzu besorgt über Code Bloat, ein Grund dafür, dass Header-Only-Version für gelegentliche Benutzer wäre. Ich dachte an Probleme wie zirkuläre Abhängigkeit oder andere unvorhergesehene Probleme, die beim Versuch auftreten könnten, eine Standardbibliothek zu konvertieren. Auch die künstliche Vorlage scheint ein Stück C++ zu sein. – manlio

+1

Ich denke, in beiden Fällen ist es wichtig zu vermeiden, dass in Ihrem Code eine Namespace-Zeile verwendet wird, die dem Endbenutzer Probleme bereiten könnte. Daher sollten Sie alles in einem Namespace implementieren (wenn Sie sie verklagt haben). Sie könnten zirkuläre Abhängigkeiten in jedem der von Ihnen erwähnten Fälle haben. – bossbarber