Il mio codice VC++ che stampa, durante la compilazione, il valore di tutte le costanti di tempo di compilazione desiderate (ad es. Sizeof structures) e continua la compilazione senza errori:
// cpptest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//#define VALUE_TO_STRING2(x) #x
//#define VALUE_TO_STRING(x) VALUE_TO_STRING2(x)
#define TO_STRING(x) #x
#define FUNC_TEMPLATE_MSG(x,y) "[" x "]""["TO_STRING(y)"]"
template<unsigned int N,unsigned int M>
int printN()
{
#pragma message(FUNC_TEMPLATE_MSG(__FUNCSIG__ ,1))
return 0;
};
struct X {
char a[20];
int b;
};
struct Y {
char a[210];
int b;
};
int _tmain(int argc, _TCHAR* argv[])
{
printN<sizeof(X),__COUNTER__>();
printN<sizeof(Y),__COUNTER__>();
//..as many compile time constants as you like
}
Esempio di output prodotto da VC++ 2010. Il valore di destinazione è il primo valore del parametro del modello di funzione (0x18 e 0xd8 nell'esempio) che VC++ ha scelto stranamente di produrre come valore esadecimale !!
1>------ Build started: Project: cpptest, Configuration: Release Win32 ------
1> cpptest.cpp
1> [int __cdecl printN<0x18,0x0>(void)][1]
1> [int __cdecl printN<0xd8,0x1>(void)][1]
1> Generating code
1> Finished generating code
1> cpptest.vcxproj -> c:\work\cpptest\Release\cpptest.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
La tecnica principale utilizzata qui è che un corso di ogni funzione di modello di istanza, la direttiva #pragma message()
viene invocato una volta. La macro specifica di Microsoft __FUNCSIG__
può visualizzare la firma della funzione di contenitore e quindi il valore intero utilizzato in ogni istanza specifica del modello di funzione. Dare COUNTER
come secondo parametro template è assicurarsi che 2 interi dello stesso valore siano ancora considerati diversi. Il 1 nella direttiva #pragma
non è utile in questo caso ma può essere utilizzato come identificativo nel caso in cui si abbia più di 1 direttiva e la finestra di output sia piena di messaggi disordinati.
L'argomento del messaggio 'static_assert' non può farlo. –
si potrebbe fare uso della diagnostica del compilatore regolare forzando un tipo incompleto in caso di errore, che dovrebbe portare alla visualizzazione degli argomenti del template nell'output del compilatore, [come qui] (http://coliru.stacked-crooked.com/a/ d2a8871788e97987) –
Posso farlo con VC++ (vedi la mia risposta). Forse qualcuno potrebbe provare a vedere se la stessa tecnica può essere utilizzata in gcc – JavaMan