简体   繁体   中英

convert a std::vector of objects from/to a std::vector of unsigned char

i have some classes defined as below, only holds some simple datatypes

class A
{
public:
  float xxx;
  int yyy;
}

i want to covert a vector of that objects to a vector of unsigned char, and vice versa. Is there a quick solution for doing that?

Thanks!

update!

thanks @Maciej Załucki, it's exactly what i need, a great help indeed, I refactored your code into the below methods.hope you dont mind.

template<typename T>
static vector<T> blob_to_vectorT(vector<unsigned char>& buffer) {
    vector<T> result(buffer.size() / sizeof(T));
    memcpy(result.data(), buffer.data(), buffer.size());
    return result;
}

template<typename T>
static vector<unsigned char> vectorT_to_blob(vector<T>& dataT) {
    int datasize = sizeof(T) * dataT.size();
    vector<unsigned char> result(datasize);
    memcpy(result.data(), dataT.data(), datasize);
    return result;
}

and i also figured it out in my own way.

template<typename T>
static vector<T> blob_to_vectorT(vector<unsigned char>& buffer) {
    const T* bytesT = reinterpret_cast<const T*>(&buffer[0]);
    vector<T> result(bytesT, bytesT + buffer.size() / sizeof(T));
    return result;
}

template<typename T>
static vector<unsigned char> vectorT_to_blob(vector<T>& dataT) {
    const unsigned char* bytes = reinterpret_cast<const unsigned char*>(&dataT[0]);
    vector<unsigned char> result(bytes, bytes + sizeof(T) * dataT.size());
    return result;
}

Let me guess, this vector of unsigned char is actually some kind of serialized data? Simplest way is just

std::vector<unsigned char> vec(sizeof(A));
memcpy(vec.data(), &a, sizeof(A));

You can do it in reverse to get your structure back. It does not care about paddings (will be copied as well). If you want one vector with many items, then simply create vector of size you want and move data by offset.

std::vector<A> source;
[...]
std::vector<unsigned char> vec(sizeof(A) * source.size());
for (size_t i = 0; i < source.size(); ++i)
{
    memcpy(vec.data() + (sizeof(A) * i), &source[i], sizeof(A));
}

Or if you want to be lazy/smart (is that synonymous?), just do that:

std::vector<A> source;
[...]
size_t dataSize = sizeof(A) * source.size();
std::vector<unsigned char> vec(dataSize);
memcpy(vec.data(), source.data(), dataSize);

As an example (no sanity checks done).

#include <iostream>
#include <vector>
#include <cstring>

class A
{
public:
    int i;
    float f;
};

int main()
{
    std::vector<A> source;
    source.push_back({1, 2.345});
    source.push_back({6, 7.89});

    // Serialize

    size_t dataSize = sizeof(A) * source.size();
    std::vector<unsigned char> vec(dataSize);
    std::memcpy(vec.data(), source.data(), dataSize);

    for (unsigned char ch : vec)
    {
        std::cout << (unsigned)ch << " ";
    }

    // Deserialize
    std::vector<A> dest(vec.size() / sizeof(A));
    std::memcpy(dest.data(), vec.data(), vec.size());

    std::cout << "\n" << dest[0].i << " " << dest[0].f;
    std::cout << "\n" << dest[1].i << " " << dest[1].f;
}

http://coliru.stacked-crooked.com/a/7801aa3a17cd171f

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM