2014-04-24 17 views
6

Vorrei scrivere una libreria C++ che è non-header-only per impostazione predefinita, ma potrebbe essere utilizzata come libreria di sola intestazione che definisce una macro NOLIB.Libreria solo intestazioni opzionale

ho visto due approcci:

  • definizioni in linea

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

  • modello "artificiale"

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

Quali sono i pro e i contro di questi approcci? Ci sono opzioni migliori?

+0

Se le funzioni sono abbastanza piccole da essere allineate, è possibile spedire le implementazioni in una libreria statica o persino spedire i file .cc. –

risposta

2

Non c'è alcuna differenza reale in ciascun approccio, in quanto sia i metodi inline che i modelli potrebbero essere inseriti in linea con il codice in base alle ottimizzazioni del compilatore. Vedi il messaggio this che discute in linea vs modelli.

+0

Non sono troppo preoccupato per il codice gonfiabile, una ragione per cui la versione di solo intestazione sarebbe per l'utente casuale. Stavo pensando a problemi come la dipendenza circolare o altri problemi imprevisti che potrebbero emergere provando a convertire una libreria standard. Anche il modello artificiale sembra un tratto di linguaggio C++. – manlio

+1

Penso che la cosa principale da tenere in considerazione in entrambi i casi è evitare di utilizzare una riga del namespace nel codice che potrebbe causare problemi all'utente finale, quindi è necessario implementare tutto all'interno di uno spazio dei nomi (se li si fa causa). Potresti avere delle dipendenze circolari in entrambi i casi che hai menzionato. – bossbarber

Problemi correlati