Преобразуйте вектор динамических собственных векторов в байты

У меня есть функция для преобразования статических векторов Eigen в вектор байтов:

template<typename T, int N>
static std::vector<uint8_t> toBytes(std::vector<Eigen::Matrix<T, N, 1>> const & vectors)
{
    std::vector<uint8_t> bytes;
    uint8_t const * rawData = reinterpret_cast<uint8_t const *>(vectors.data());
    bytes.insert(bytes.end(), rawData, rawData + vectors.size() * N * sizeof(T));
    return bytes
}

Этого было достаточно, пока не появились динамические векторы Eigen (то есть Eigen::VectorXf), у которых N установлено на -1. Итак, я придумал это:

template<typename T>
static std::vector<uint8_t> toBytes(std::vector<Eigen::Matrix<T, -1, 1>> const & vectors)
{
    std::vector<uint8_t> bytes;
    uint8_t const * rawData = reinterpret_cast<uint8_t const *>(vectors.data());
    bytes.insert(bytes.end(), rawData, rawData + vectors.size() * sizeof(vectors[0]));
    return bytes
}

Однако это приводит к тому, что вектор в четыре раза больше, чем ожидалось, поэтому я предполагаю, что динамические векторы нельзя тривиально преобразовать в байты как статический вектор. Я могу решить проблему с размером следующим образом:

template<typename T>
static std::vector<uint8_t> toBytes(std::vector<Eigen::Matrix<T, -1, 1>> const & vectors)
{
    std::vector<uint8_t> bytes;
    uint8_t const * rawData = reinterpret_cast<uint8_t const *>(vectors.data());
    bytes.insert(bytes.end(), rawData, rawData + vectors.size() *  vectors[0].size() * sizeof(T));
    return bytes
}

В результате получается вектор правильной длины, заполненный значениями, но эти значения неверны. Как я могу преобразовать вектор динамических векторов Eigen в вектор байтов?


person Jerome Reinländer    schedule 20.06.2019    source источник


Ответы (1)


Хорошо, есть одно очень очевидное решение:

template<typename T>
static std::vector<uint8_t> createBuffer(std::vector<Eigen::Matrix<T, -1, 1>> const & vectors)
{
    std::vector<uint8_t> & bytes = buffer.bytes;
    bytes.reserve(vectors.size() * vectors[0].size() * sizeof(T));

    for (auto const & vector : vectors)
    {
        for (int i = 0; i < vector.size(); ++i)
        {
            uint8_t const * rawData = reinterpret_cast<uint8_t const *>(&vector(0));
            bytes.insert(bytes.end(), rawData, rawData + sizeof(T));
        }
    }

    return bytes;
}
person Jerome Reinländer    schedule 20.06.2019
comment
reserve будет неоптимальным, если записи vectors имеют разные размеры. И, конечно же, содержимого bytes будет недостаточно, чтобы воссоздать из него тот же vectors (нужна дополнительная информация об отдельных размерах). - person chtz; 21.06.2019
comment
@chtz Вы правы! Это работает только для моего случая, так как все собственные векторы имеют одинаковый размер. Я не думаю, что есть общее решение этой проблемы, поскольку вам придется сохранять дополнительные данные о длине каждого собственного вектора. - person Jerome Reinländer; 22.06.2019