2016-06-17 16 views
3

Ich entwickle einen Parser der Schriftart Adobe Type 1 in C++ - Sprache. Und es gab ein Problem, als ich versuchte, die DICT-Daten zu dekodieren.Unbestimmter Rückgabetyp einer Funktion

Die Operanden im DICT, die als Bytefolge in der PDF-Datei gespeichert sind, können entweder eine Ganzzahl oder eine reelle Zahl sein.

Ich definierte eine Funktion, deren Prototyp getOperandVal(unsigned char* buf) ist, um die Sequenz zu nummerieren. Und das Problem ist erschienen.

Bevor wir den Buf analysieren, können wir nicht wissen, ob der Buf real oder eine ganze Zahl ist. Daher kann ich den Rückgabewerttyp nicht bestimmen, der int oder double sein sollte.

Eine Lösung besteht darin, eine Struktur als Rückgabewerttyp zu verwenden. Die Struktur ist wie folgt:

typedef struct 
{ 
    int interger; 
    double real; 
    bool bReal; 
}RET; 

Dann ist die Funktion Prototyp ist:

RET getOperandVal(unsigned char* buf); 

Aber ich denke, es ist nicht kompakt ist. Vor allem ist es unbequem zu verwenden. Zweitens wird das Programm langsamer ausgeführt, wenn die Datenmenge groß ist.

Kann mir jemand eine bessere Lösung geben? Kann Vorlage es tun?

Vielen Dank!

Addition: Das Programm wird den Operandenwert in Byte-Sequenz übertragen, um nach der Bearbeitung in Datei umgeschrieben zu werden. Betrachten Sie bitte die Anforderung.

+0

Könnten Sie trivialy (das heißt nicht voll Parsing) entscheiden, ob 'buf' enthält' int' oder 'double'? Dann könnten Sie 'if (tryParse (buf)) ' – Zereges

Antwort

0

Schablonentypen werden zum Zeitpunkt der Kompilierung ausgewertet, der Funktionsprototyp konnte nicht dynamisch geändert werden. Sie könnten entweder den Rückgabewert auf die größte Größe hochskalieren (z. B. immer double zurückgeben), eine Struktur zurückgeben oder eine Variantenimplementierung verwenden, z. B. boost::variant.

+0

" upscale Rückgabewert auf die größte Größe "kann nützlich sein. Ich kann einen Dezimalpunkt und 0 am Ende einer Ganzzahl hinzufügen, genau wie '.0' zu 1234 hinzufügen, um es zu 1234.0 zu machen. Ermitteln Sie den Typ, wenn ich den Rückgabewert verwende. Aber die Bestimmung wird falsch sein, wenn der ursprüngliche Typ doppelt ist und der Wert 1234.0 ist. Adobe Type1 kann eine echte Nummer wie 365.0 verwenden, um die Schriftartversion anzuzeigen. –

1

Sie können keine Vorlagen verwenden, da Sie zur Kompilierzeit nicht wissen, welcher Typ zurückgegeben wird.

Aber man kann ein union verwenden: es ist sicher, indem sie

struct Int_real { 
    union { 
    int integer; 
    double real; 
    }; 
    bool is_real; 
}; 

Eine sehr gute Idee ist, zu verbessern, darauf (Zugang ermöglichen, nur das Feld der Vereinigung, die aktiv ist).

Schon bald (hoffentlich), können Sie std::any verwenden

+1

Sie könnten z.B. 'boost :: variant' oder eine andere Variantenimplementierung. – Jens

+0

@Jens ja, aber es gibt bereits eine Antwort, die auf die Variante hinweist – bolov