2016-07-10 13 views
2

Aus irgendeinem Grund (ehm CUDA) Ich verwende printf() in meinem C++ - Code. Ich möchte in der Lage sein, einige dieser Anwendungen zu modellieren - aber dafür muss ich den printf-Spezifizierer für verschiedene Typen erhalten. Angenommen, ich brauche das nur für Typen, die tatsächlich relevante Spezifizierer haben; und dass mir die wissenschaftliche vs. Dezimalschreibweise und andere solche Details nicht wirklich wichtig sind.Idiomatische Art, einen Druckspezifizierer für einen Typ zu erhalten?

Gibt es einen idiomatischen Weg, dies zu tun, außer eine Nachschlagetabelle zu haben?

Hinweis: Ich möchte, dass alles zur Kompilierzeit geschieht, keine Laufzeit. Trotz printf() selbst analysiert es nur zur Laufzeit.

Antwort

3

würde ich so etwas wie folgt verwenden:

template <typename T> struct PrintfSpecifier; 
#define TYPE_SPEC(type, spec) \ 
    template <> struct PrintfSpecifier<type>{static constexpr const char *value = spec;} 
TYPE_SPEC(int   , "%d"); 
TYPE_SPEC(unsigned int , "%u"); 
// More types here... 
#undef TYPE_SPEC 

Und Ihre Schnur bekommen Sie PrintfSpecifier<int>::value verwenden können.


Wenn Sie in der Lage C++ 14 und Sie wie ausgefallene Funktionen zu benutzen, gibt es eine saubere Alternative:

template <typename T> constexpr const char *printf_specifier = ""; 
#define TYPE_SPEC(type, spec) \ 
    template <> constexpr const char *printf_specifier<type> = spec; 
    TYPE_SPEC(int   , "%d"); 
TYPE_SPEC(unsigned int , "%u"); 
// More types here... 
#undef TYPE_SPEC 
+2

Sie brauchen ein bisschen vorsichtig, weil diese 'const char sein * 's haben keine Verknüpfung, also, wenn Sie jemals eine Funktion haben, die ein const Char * durch Verweis nimmt und versuchen, dies zu übergeben, erhalten Sie bizarre und nicht hilfreiche Linker-Fehler. –

+0

@NirFriedman Guter Punkt, aber ich denke nicht, dass es ein Problem ist. Const-Referenzen funktionieren gut damit und nicht-konstante Referenzen sollten sowieso nicht mit Konstanten arbeiten. – HolyBlackCat

+0

Sie schlagen im Grunde vor, was ich vorhatte und hoffte zu vermeiden :-(Auch würde ich das Makro DEFINE_PRINTF_SPECIFIER machen, um die Wahrscheinlichkeit einer Namenskollision zu reduzieren; TYPE() ist wahrscheinlich schon von jemandem definiert worden. – einpoklum

Verwandte Themen