Проблема с нетривиально копируемыми типами данных 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;
}
→ Ссылка