Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与特征数据类型的并集_C++_Eigen_Unions - Fatal编程技术网

C++ 与特征数据类型的并集

C++ 与特征数据类型的并集,c++,eigen,unions,C++,Eigen,Unions,我一直在使用union测试Egeng库数据类型,以进行类型双关。我的目的是有一个双数组的单内存,可以作为特征数据类型访问,反之亦然 例如: union BigBox{ double X[13]; struct { Eigen::Vector3d p; Eigen::Vector3d v; Eigen::Vector3d w; Eigen::Vector4d q; } data; }; 当我测试 s

我一直在使用union测试Egeng库数据类型,以进行类型双关。我的目的是有一个双数组的单内存,可以作为特征数据类型访问,反之亦然

例如:

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特性,但是在这种情况下,我有没有办法使用类型双关呢?我想要实现的正确方法是什么?

默认情况下,
Eigen::Vector4d
是16字节对齐的(或者使用AVX编译时是32字节对齐的,更准确地说,它将对齐)。 这意味着在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); }
struct BigBox{
特征矩阵X;
Eigen::Ref p(){return X.segment(0);}
特征::Ref p()常量{返回X.segment(0);}
Eigen::Ref v(){return X.segment(3);}
特征::Ref v()常量{返回X.segment(3);}
Eigen::Ref w(){返回X.segment(6);}
本征::Ref w()常量{返回X.segment(6);}
Eigen::Ref q(){return X.segment(9);}
特征::Ref q()常量{返回X.segment(9);}

})

与SIMD无关,编译器已将其填充为16字节的倍数,即在结构末尾额外分配了8个匿名字节。这是一种依赖于编译器的行为,但通常情况下,如果结构>2字节,它将填充为2的倍数,如果>4字节,则填充为4的倍数,依此类推。谢谢@Ben,但我意识到,根据结构中向量的顺序,填充的位置会有所不同。也就是说,如果我尝试用一个从1到13的序列加载X,并通过p,v,w,q读取它,丢失的数字并不总是相同的。是否仍有指定填充字节位置的方法?放入显式填充:
Eigen::Vector3d p;双未使用1;本征::矢量3D v;双未使用2等等。还要查看编译器文档中的对齐指令,因为这是特定于平台的东西。注意,我不熟悉Egeng-如果这些类型有构造函数或析构函数,那么这样做是不安全的。