объединение с собственными типами данных - PullRequest
0 голосов
/ 29 декабря 2018

Я тестировал типы данных библиотеки Eigen с объединением для определения типов.Мое намерение состоит в том, чтобы иметь одну память двойного массива, к которой можно обращаться как к собственному типу данных, и наоборот.

пример:

union BigBox{
    double X[13];
    struct
    {
        Eigen::Vector3d p;
        Eigen::Vector3d v;
        Eigen::Vector3d w;
        Eigen::Vector4d q;
    } data;

};

Когда я проверяю

sizeof(BigBox)/sizeof(double) = 14
sizeof(Eigen::Vector3d)/sizeof(double) = 3
sizeof(Eigen::Vector4d)/sizeof(double) = 4

Размер структуры не складывается.Как получить дополнительный +1?Я полагаю, что это может быть из-за того, что компилятор пытается использовать функции SMID, но есть ли какой-нибудь способ для меня, чтобы в этих ситуациях использовать наказание типов?Как правильно подходить к тому, чего я пытаюсь достичь?

1 Ответ

0 голосов
/ 29 декабря 2018

По умолчанию Eigen::Vector4d выровнено на 16 байтов (или выровнено на 32 байта при компиляции с AVX, точнее, будет выровнено по EIGEN_MAX_STATIC_ALIGN_BYTES).Это означает, что после 3 векторов по 3 * 8 байтов каждый (= 72 байта) будет 8 дополнительных байтов.Вы можете обойти это, либо поместив наиболее выровненный элемент в начале, либо локально отключив выравнивание .

Ничто из этого не является действительно безопасным, поскольку в объединениях C ++ должноне следует использовать для определения типа - хотя это часто работает на практике.

Чтобы быть немного более безопасным, вы можете сделать что-то вроде этого:

struct BigBox{
    Eigen::Matrix<double,13,1> X;

    Eigen::Ref<Eigen::Vector3d      > p()       { return X.segment<3>(0); }
    Eigen::Ref<Eigen::Vector3d const> p() const { return X.segment<3>(0); }
    Eigen::Ref<Eigen::Vector3d      > v()       { return X.segment<3>(3); }
    Eigen::Ref<Eigen::Vector3d const> v() const { return X.segment<3>(3); }
    Eigen::Ref<Eigen::Vector3d      > w()       { return X.segment<3>(6); }
    Eigen::Ref<Eigen::Vector3d const> w() const { return X.segment<3>(6); }
    Eigen::Ref<Eigen::Vector4d      > q()       { return X.segment<4>(9); }
    Eigen::Ref<Eigen::Vector4d const> q() const { return X.segment<4>(9); }

};

...