Ho un contatore di compilazione che ho utilizzato per anni, ispirato allo these answers. Funziona in C++ 03/11 e per quanto ho testato, relativamente pure sulle principali compilatori:Contatore del tempo di compilazione nella classe template
namespace meta
{
template<unsigned int n> struct Count { char data[n]; };
template<int n> struct ICount : public ICount<n-1> {};
template<> struct ICount<0> {};
#define MAX_COUNT 64
#define MAKE_COUNTER(_tag_) \
static ::meta::Count<1> _counter ## _tag_ (::meta::ICount<1>)
#define GET_COUNT(_tag_) \
(sizeof(_counter ## _tag_ (::meta::ICount<MAX_COUNT + 1>())) - 1)
#define INC_COUNT(_tag_) \
static ::meta::Count<GET_COUNT(_tag_) + 2> _counter ## _tag_ (::meta::ICount<2 + GET_COUNT(_tag_)>)
}
Il seguente test compiles and runs perfectly (expected uscita è 0 1 2 3
):
struct Test
{
MAKE_COUNTER(uu);
static const unsigned int a = GET_COUNT(uu);
INC_COUNT(uu);
static const unsigned int b = GET_COUNT(uu);
INC_COUNT(uu);
static const unsigned int c = GET_COUNT(uu);
INC_COUNT(uu);
static const unsigned int d = GET_COUNT(uu);
};
template<typename T>
void test()
{
std::cout << T::a << " " << T::b << " " << T::c << " " << T::d << "\n";
}
int main()
{
test<Test>();
}
Tuttavia, Ho trovato un caso in cui vedo un comportamento molto strano con clang e gcc. Se si modifica Test
come struttura del modello, prendendo un esempio per esempio (template<int> struct Test
e test<Test<42> >()
in main
), clang and gcc both fail to compile, si lamenta che sto ridefinendo la funzione contatore (mentre msvc lo compila senza problemi). Per qualche motivo il compilatore non riesce a calcolare una sizeof in una classe template.
clang trovare l'errore nel terzo INC_COUNT
, mentre gcc lo trova nella seconda.
ho ampliato manualmente questa macro, e:
per clang, dà
static ::meta::Count<GET_COUNT(uu)+2> _counteruu(::meta::ICount<(sizeof(_counteruu(::meta::ICount<65>())) - 1)+2>); // ^ ^
rimuovendo le parentesi sottolineate risolve il problema.
per gcc: spostare il
+2
prima dellasizeof
è l'unico lavoro intorno
La nota triste è che queste soluzioni alternative sembrano non funzionare quando incluso nelle macro. È come se il compilatore dimenticasse solo come calcolare il risultato di sizeof dopo un po 'di tempo ...
Perché sta succedendo? Sto facendo qualcosa di sbagliato, o sono solo bug del compilatore (dato che clang e gcc non riportano nemmeno la stessa riga)?
Nota: so there is a gcc bug about this counter. La domanda non riguarda questo bug.
(Ignora tutti i miei commenti precedenti, che ho ora eliminato.Essi non erano corretti.Ho ampliato manualmente alcuni dei modelli e non ricordavo abbastanza correttamente quali esperimenti avevo fatto.) –