Проблема с нетривиально копируемыми типами данных std::string std::vector
Необходимо отправлять и получать сообщения не только тривиально копируемыми типами.
Я могу передать в msg массив std::array, так же могу получить из msg этот массив, но это при условии того что я знаю длину сообщения при компиляции, у меня же нет такой возможности, я могу узнать длину только во время выполнения при помощи int x = msg.size();
, как мне добавить возможность передавать и получать std::string и std::vector
Передаю данные
std::array<char, 5> data = { 'h', 'e', 'l', 'l', 'o' };
msg << data;
Send(msg);
Получаю данные
std::array<char, 5> data;
msg >> data;
for (size_t i = 0; i < 5; i++)
{
std::cout << data[i];
}
// Pushes any POD-like data into the message buffer
template<typename DataType>
friend message<T>& operator << (message<T>& msg, const DataType& data)
{
// Check that the type of the data being pushed is trivially copyable
static_assert(std::is_standard_layout<DataType>::value, "Data is too complex to be pushed into vector");
// Cache current size of vector, as this will be the point we insert the data
size_t i = msg.body.size();
// Resize the vector by the size of the data being pushed
msg.body.resize(msg.body.size() + sizeof(DataType));
// Physically copy the data into the newly allocated vector space
std::memcpy(msg.body.data() + i, &data, sizeof(DataType));
// Recalculate the message size
msg.header.size = msg.size();
// Return the target message so it can be "chained"
return msg;
}
// Pulls any POD-like data form the message buffer
template<typename DataType>
friend message<T>& operator >> (message<T>& msg, DataType& data)
{
// Check that the type of the data being pushed is trivially copyable
static_assert(std::is_standard_layout<DataType>::value, "Data is too complex to be pulled from vector");
// Cache the location towards the end of the vector where the pulled data starts
size_t i = msg.body.size() - sizeof(DataType);
// Physically copy the data from the vector into the user variable
std::memcpy(&data, msg.body.data() + i, sizeof(DataType));
// Shrink the vector to remove read bytes, and reset end position
msg.body.resize(i);
// Recalculate the message size
msg.header.size = msg.size();
// Return the target message so it can be "chained"
return msg;
}
Ответы (1 шт):
Автор решения: HAVLOK
→ Ссылка
Нашел решение, изменил функции что бы они работали с std::string Передаем данные
std::string data = "hello";
msg << data;
Send(msg);
Получаем данные
std::string data;
msg >> data;
std::cout << data;
template<typename T>
friend message<T>& operator << (message<T>& msg, const std::string& data)
{
uint32_t dataSize = static_cast<uint32_t>(data.size());
msg.body.insert(msg.body.end(), reinterpret_cast<const uint8_t*>(&dataSize), reinterpret_cast<const uint8_t*>(&dataSize) + sizeof(uint32_t));
msg.body.insert(msg.body.end(), data.begin(), data.end());
msg.header.size = msg.size();
return msg;
}
template<typename T>
friend message<T>& operator >> (message<T>& msg, std::string& data)
{
if (msg.body.size() < sizeof(uint32_t))
return msg;
uint32_t dataSize;
std::memcpy(&dataSize, msg.body.data(), sizeof(uint32_t));
msg.body.erase(msg.body.begin(), msg.body.begin() + sizeof(uint32_t));
if (msg.body.size() < dataSize)
return msg;
data.resize(dataSize);
std::memcpy(&data[0], msg.body.data(), dataSize);
msg.body.erase(msg.body.begin(), msg.body.begin() + dataSize);
return msg;
}