2016-06-17 16 views
3

私はC++言語を使ってAdobe Type 1フォントのパーサを開発しています。 DICTデータをデコードしようとすると問題が発生します。関数の返り値の型が不確定

DICT内のオペランドは、PDFファイルにバイトシーケンスとして格納され、整数または実数のいずれかになります。

プロトタイプがgetOperandVal(unsigned char* buf)である関数を定義して、シーケンスを数値にデコードしました。そして問題は現れた。

bufを解析する前に、bufが実数または整数であることはわかりません。戻り値の型は、intまたはdoubleである必要があります。

戻り値型としてstructを使用する方法があります。構造体は以下のようなものです:

RET getOperandVal(unsigned char* buf); 

しかし、私はそれがコンパクトではないと思う:

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

次に、関数のプロトタイプです。まず、使用するのは不便です。第二に、データのサイズが大きい場合、プログラムの実行速度が遅くなります。

もっと良い解決策を教えてもらえますか?テンプレートはそれを行うことができますか?

ありがとうございました!

追加: プログラムは、編集後にファイルに書き換えるためにオペランド値をバイトシーケンスに転送します。要件を考慮してください。

+0

を使用することができるでしょうか?それで 'if(tryParse(buf))' – Zereges

答えて

0

コンパイル時にテンプレートの型が評価されるため、関数のプロトタイプを動的に変更できませんでした。戻り値を最大サイズ(例えば常にdoubleを返す)にアップスケールするか、構造体を返すか、またはboost::variantのようないくつかのバリアント実装を使用することができます。

+0

"最大のサイズへの高級戻り値"が役に立ちます。小数点と0を整数の末尾に追加することができます.1234.0にするために '.0'を1234に追加するのと同じです。戻り値を使用するときの型を決定します。しかし、元の型がdouble型で値が1234.0の場合、判定は間違っています。 Adobe Type1は、フォントバージョンを提示するために365.0などの実数を使用する場合があります。 –

1

コンパイル時に返される型がわからないため、テンプレートは使用できません。

しかし、あなたが使用することができunion

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

非常に良いアイデアは、それが安全(アクティブである労働組合の唯一のフィールドへのアクセスを許可する)ことによって、それを改善することです。

もうすぐ(うまくいけば)、あなたはtrivialy(フルパースないすなわち)buf`は `int`または` double`が含まれているかどうかを決める `でしstd::any

+1

'boost :: variant'や別のバリアントの実装です。 – Jens

+0

@Jensはい、しかし、既に異形を指摘する回答があります – bolov

関連する問題