2016-06-17 216 views
3

我正在使用C++語言開發Adobe Type 1字體的解析器。當我嘗試解碼DICT數據時出現問題。函數的不確定返回類型

DICT中作爲字節序列存儲在PDF文件中的操作數可以是整數或實數。

我定義了一個函數,其原型爲getOperandVal(unsigned char* buf),將序列解碼爲數字。問題出現了。

解析buf之前,我們無法知道buf是實數還是整數。所以我不能確定返回值類型,它應該是intdouble

解決方案是使用結構作爲返回值類型。該結構是象下面這樣:

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

然後函數原型爲:

RET getOperandVal(unsigned char* buf); 

但我認爲這是不緊湊。首先,使用起來不方便。其次,當數據量很大時,程序運行速度會變慢。

任何人都可以給我一個更好的解決方案嗎?模板能做到嗎?

非常感謝!

此外: 程序會將操作數值轉換爲字節序列,以便在編輯後重寫入文件。請考慮這項要求。

+0

你能trivialy(即不完全解析)決定是否buf'''包含或int''double'?然後你可以做'if(tryParse(buf))' – Zereges

回答

0

模板類型是在編譯時計算的,你不能動態改變函數原型。你可以將返回值放大到最大值(例如總是返回double),返回一個結構體或使用一些變體實現,如boost::variant

+0

「高檔返回值到最大尺寸」可能會有用。我可以添加一個小數點和0到一個整數的末尾,就像添加'.0'到1234使它成爲1234.0。確定我使用返回值時的類型。但是當原始類型是double並且值是1234.0時,確定將是錯誤的。 Adobe Type1可能會使用實際的數字(如365.0)來顯示字體版本。 –

1

你不能使用模板,因爲你不知道在編譯時什麼類型將被返回。

但是你可以使用一個union

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

一個很好的想法是通過使安全(允許訪問是積極的工會只有場)在其改善。

很快(希望),你將能夠使用std::any

+1

您可以使用例如'boost :: variant'或其他變體實現。 – Jens

+0

@Jens是的,但已經有一個答案指出了變體 – bolov