2015-03-13 4 views
0

Общий вопрос о поддержке и обработке нескольких разных целочисленных размеров и следует ли их рассматривать как независимые типы (например, string vs int) или одно подмножество другого. В частности, я рассматриваю uint8_t и uint32_t.Обработка целых чисел разного размера

Я хочу создать объект сообщения, который я буду использовать для отправки сообщения по сети. В простейшем случае он будет иметь заголовок, содержащий размер полезной нагрузки и полезную нагрузку. У меня есть 3 типа данных для отправки.

  1. Строковые данные, где заголовок представляет собой длину строки, а полезная нагрузка - это строка.
  2. 1 байтовые целочисленные данные, где заголовок равен 1, а полезная нагрузка - uint8_t.
  3. 4 байтовых целочисленных данных, где заголовок равен 4, а полезная нагрузка - uint32_t.

(На самом деле, я также использую один бит заголовка, чтобы указать, является ли это int или строковым типом, но здесь это не очень важно).

При создании моего объекта сообщения, очевидно, я рассматриваю строку как отличную от целого, и у нее есть свой собственный конструктор для создания необработанного сообщения. Я пытаюсь определить, что лучше всего подходит для разных типов целых чисел.

Я мог:

  1. Рассматривать их отдельно. Имеют два конструктора, один принимает uint8_t и один принимает uint32_t.
  2. Рассматривайте uint8_t как подмножество uint32_t и имея один конструктор, принимающий uint32_t, а затем проверяете, являются ли его самые значимые три байта равными нулю.

В конечном счете, я хотел бы иметь поддержку целых чисел 1, 2, 4 и 8 байтов и не нравится идея распространения в конструкторах, которые я получил бы, если бы взял вариант 1, общий конструктор и проверить значение того, что я передал, чтобы определить, какой тип он должен быть. Однако я хочу сделать «правильную» вещь. Поэтому мой вопрос заключается в том, что ... должны uint8_t и uint32_t рассматриваться как отдельные типы, так же, как и строка и uint8_t. Или это хорошая практика, чтобы рассмотреть uint8_t как подмножество uin32_t?

+0

Почему бы не использовать третий сторонней сетевой библиотеки? У них обычно есть функции потока, такие как push_int8 push_int32 и т. Д. Затем вы можете отправлять участников, как хотите. Это даже не должно быть одного типа, если вы используете int для хранения только небольших значений в вашем объекте. –

+1

Я бы сказал, что первый вариант - это хороший способ. Цель типов - переносить информацию во время компиляции; второй вариант отбросит эту информацию. Я бы посоветовал написать общий шаблонный метод для интегральных типов. – lisyarus

+0

Является ли объект сообщения предназначенным быть строго транспортным механизмом или он также предназначен для передачи типа?Если вы создадите отдельные конструкторы для разных целых типов, вы получите ошибки, поскольку целые числа неявно конвертируются. –

ответ

0

Как я уже сказал в комментариях, первый вариант лучше, так как он использует информацию о типе, которую вы имеете. Нет необходимости создавать разные конструкторы сообщений для uint8, uint32 и других; шаблоны помогут вам.

Вот пример типичного сообщения, построения функции, которая работает для всех типов POD:

template <typename T, typename = std::enable_if<std::is_pos<T>::value, void>::type> 
message create_message (T const & x) 
{ 
    message m; 
    m.write(&x, sizeof(T)); 
    return m; 
} 

(я предполагаю, что ваш message тип имеет некоторый метод, как write(void*, size_t))

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