Как скопировать int в массив boost / std :: char?

Что является наиболее простым и эффективным, почему копировать int в boost / std :: array?

Кажется, что работает следующее, но я не уверен, что это самый подходящий способ сделать это:

  int r = rand();
boost::array<char, sizeof(int)> send_buf;
std::copy(reinterpret_cast<char*>(&r), reinterpret_cast<char*>(&r + sizeof(int)), &send_buf[0]);

0

Решение

Просто для сравнения вот то же самое с memcpy:

#include <cstring>

int r = rand();
boost::array<char, sizeof(int)> send_buf;
std::memcpy(&send_buf[0], &r, sizeof(int));

Ваш призыв к тому, является ли взрыв приведений (и возможность их ошибиться) лучше или хуже, чем «грех» C ++ использования функции, также присутствующей в C 😉

Лично я считаю memcpy является довольно хорошим «сигналом тревоги» для такого рода операций, по той же причине, по которой приведения в стиле C ++ являются хорошим «сигналом тревоги» (легко обнаружить во время чтения, легко найти). Но вы можете предпочесть иметь одинаковый сигнал тревоги для всего, и в этом случае вы можете привести аргументы memcpy в void*,

Кстати, я мог бы использовать sizeof r для обоих размеров, а не sizeof(int), но это в некотором роде зависит от того, требует ли контекст, чтобы массив «был достаточно большим для r (который оказывается целым числом)» или «имеет тот же размер, что и int (который оказывается случаем r)». Так как это буфер отправки, я полагаю, что размер буфера соответствует требуемому протоколу r должен соответствовать буферу, а не наоборот. Так sizeof(int) вероятно уместно, но 4 или же PROTOCOL_INTEGER_SIZE может быть еще более уместным.

4

Другие решения

Идея верна, но у вас есть ошибка:

reinterpret_cast<char*>(&r + sizeof(int))

Должно быть:

reinterpret_cast<char*>(&r) + sizeof(int)

или же

reinterpret_cast<char*>(&r+1)

Эти или memcpy эквивалентны в порядке. Все остальное рискует проблемами выравнивания.

3

Это общая валюта для использования reinterpret_cast для этих целей, но Стандарт проясняет, что static_cast с помощью void* вполне приемлемо. На самом деле в случае типа, как int затем reinterpret_cast<char*>(&r) является определенный иметь семантику static_cast<char*>(static_cast<void*>(&r)), Почему бы не быть явным и использовать это прямо?

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

Обратите внимание, что вам разрешено обрабатывать указатель на один объект, как если бы он был указателем на массив из одного объекта (см. 5.7 / 4). Это удобно для получения второго указателя.

int r = rand();
boost::array<char, sizeof(int)> send_buf;
auto cast = [](int* p) { return static_cast<char*>(static_cast<void*>(p)); };
std::copy(cast(&r), cast(&r + 1), &send_buf[0]);
2

Незначительная ошибка, на которую указал Майкл Андерсон

Но вы могли бы сделать это:

#include <iostream>

union U
{
int  intVal;
char charVal[sizeof(int)];
};

int main()
{
U   val;
val.intVal  = 6;

std::cout <<  (int)val.charVal[0] << ":" << (int)val.charVal[1] << ":" << (int)val.charVal[2] << ":" << (int)val.charVal[3] << "\n";
}
0
По вопросам рекламы [email protected]