Benutzer definierte Konvertierungsoperator als Argument für printf
-
21-09-2019 - |
Frage
Ich habe eine Klasse, die einen benutzerdefinierten Operator für einen TCHAR * definiert ist, wie so
CMyClass::operator const TCHAR*() const
{
// returns text as const TCHAR*
}
Ich möchte in der Lage sein, etwas zu tun, wie
CMyClass myClass;
_tprintf(_T("%s"), myClass);
oder auch
_tprintf(_T("%s"), CMyClass(value));
Aber wenn man versucht, printf immer druckt (null) anstelle des Wertes. Ich habe auch einen normalen char * Operator sowie Variationen mit konst usw. versucht Es funktioniert nur richtig, wenn ich den Bediener explizit aufrufen oder eine Besetzung tun, wie
_tprintf(_T("%s\n"), (const TCHAR*)myClass);
_tprintf(_T("%s\n"), myClass.operator const TCHAR *());
Aber ich will nicht gegossen. Wie kann dies erreicht werden?
Beachten Sie, dass die Möglichkeit besteht, eine Funktion zu erstellen, die einen Parameter const TCHAR * hat, so dass es gewaltsame Anrufe der Betreiber TCHAR *, aber das ich nicht implementieren auch wollen.
Lösung
Vermeiden Umwandlung Betreiber. Sie tun selten, was Sie wollen, und dann explizite Anrufe sind schmerzhaft. Benennen Sie operator const TCHAR*() const
zu TCHAR *str() const
.
Andere Tipps
Der C ++ Standard besagt, dass die impliziten Konvertierungen wie diese nicht zu Ellipsen Parameter angewandt werden - wie würde die Compiler wissen, was Konvertierung anwenden? Sie werden die Konvertierung explizit selbst ausführen müssen, oder besser noch mit printf stoppen.
Conversion Operatoren werden aufgerufen, wenn der Compiler will einen Wert in einem anderen Typ konvertieren. Dies funktioniert für Funktionen, die definierten Parameter bestimmter Arten nehmen. Es funktioniert nicht für variadische Funktionen wie printf()
mit ...
in der Funktionsdeklaration. Diese Funktionen nehmen die Argumente und dann mit ihnen arbeiten, so dass der Umwandlungsoperator nie aufgerufen wird.
Um genau zu sein, wenn der Compiler printf("%s", foo)
sieht, geht es foo
, was immer es ist, zu printf()
, das es ist geeignet für ein %s
Format muss davon ausgehen, wie es ist. Es wird kein Umwandlungsoperator (obwohl bestimmte arithmetische Aktionen stattfinden).
Conversion-Betreiber in der Regel zu Problemen führen. dass Betreiber in dieser Klasse, indem er, haben Sie Funktion Überlastung Auflösung kompliziert, da der Compiler eine CMyClass
interpretieren kann, als ob es sich um eine TCHAR *
waren. Dies kann zu unerwarteten Ergebnissen führen, entweder verursacht Code zu kompilieren, wenn Sie wirklich nicht wollen, dass es zu, oder die falsche überladene Funktion auswählen. (Zum Beispiel gegeben CMyClass cmc;
der Ausdruck cmc + 10
plötzlich legal ist, da TCHAR * + int
ist vollkommen legitim Pointer-Arithmetik.) Die übliche Praxis ist eine solche Umwandlungen explicit
beschriften.
Casting ist das Richtige zu tun, wenn Sie auf einem Konvertierungsoperator printf Stil APIs und verlassen verwenden möchten (und ich werde hier nicht darüber streiten, ob oder nicht, sollten Sie diese Funktionen verwenden). Allerdings würde ich statischen Guss verwenden, z.B. _tprintf(_T("%s\n"), static_cast<const TCHAR*>(myClass));