Я занимаюсь разработкой парсера шрифта 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);
Но я думаю, что это не компактно. Прежде всего, это неудобно в использовании. Во-вторых, программа будет работать медленнее, когда размер данных большой.
Кто-нибудь может дать мне лучшее решение? Может шаблон сделать это?
Большое спасибо!
Дополнение:
Программа передаст значение операндов в байтовую последовательность для перезаписи в файл после редактирования. Рассмотрите требование, пожалуйста.
Вы не можете использовать шаблоны, потому что вы не знаете во время компиляции, какой тип будет возвращен.
Но вы можете использовать союз:
struct Int_real {
union {
int integer;
double real;
};
bool is_real;
};
Очень хорошая идея — улучшить его, сделав его безопасным (разрешить доступ только к активной области объединения).
Довольно скоро (надеюсь), вы сможете использовать станд :: любой
Типы шаблонов оцениваются во время компиляции, вы не можете динамически изменять прототип функции. Вы можете либо увеличить возвращаемое значение до самого большого размера (например, всегда возвращать double), вернуть структуру или использовать некоторую реализацию варианта, например boost::variant
,