2016-06-17 3 views
3

Я разрабатываю синтаксический анализатор шрифта Adobe Type 1 с использованием языка C++. И есть проблема, когда я пытался декодировать данные DICT.Неопределенный тип возвращаемого значения функции

Операнды в DICT, которые хранятся в виде последовательности байтов в файле PDF, могут быть либо целыми, либо действительными.

Я определил функцию, прототип которой составляет getOperandVal(unsigned char* buf), чтобы декодировать последовательность до номера. И проблема возникла.

Прежде чем разобрать buf, мы не можем знать, что buf является реальным или целым числом. Поэтому я не могу определить тип возвращаемого значения, который должен быть int или double.

Решение состоит в использовании структуры как типа возвращаемого значения. Структура, как показано ниже:

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. Определите тип, когда я использую возвращаемое значение. Но определение будет неправильным, если исходный тип будет двойным, а значение - 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

@ Да, да, но уже есть ответ, указывающий вариант – bolov

Смежные вопросы