Что является наиболее простым и эффективным, почему копировать 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]);
Просто для сравнения вот то же самое с 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
может быть еще более уместным.
Идея верна, но у вас есть ошибка:
reinterpret_cast<char*>(&r + sizeof(int))
Должно быть:
reinterpret_cast<char*>(&r) + sizeof(int)
или же
reinterpret_cast<char*>(&r+1)
Эти или memcpy
эквивалентны в порядке. Все остальное рискует проблемами выравнивания.
Это общая валюта для использования 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]);
Незначительная ошибка, на которую указал Майкл Андерсон
Но вы могли бы сделать это:
#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";
}