C++ 将一种数据类型的向量复制到同一数据类型的结构向量的有效方法是什么?

C++ 将一种数据类型的向量复制到同一数据类型的结构向量的有效方法是什么?,c++,vector,struct,memory-alignment,C++,Vector,Struct,Memory Alignment,我有一个结构向量,有3个成员变量(vec3)pos(vec3)norm(vec2)texCoord,还有另外3个独立向量(vec3)x(vec3)y(vec2)z,我想复制/合并 将独立向量中的数据转换成我上面提到的结构数据类型的向量,这样变量将根据结构中的变量对齐。 我可以通过迭代向量的每个成员并分配变量来对此进行归档,但是我正在寻找一种更快更有效的方法,通过一个或两个函数调用将向量的整个范围复制到另一个向量,有没有这样的方法来实现这一点 伪代码: struct foo { vec3 pos;

我有一个结构向量,有3个成员变量(vec3)pos(vec3)norm(vec2)texCoord,还有另外3个独立向量(vec3)x(vec3)y(vec2)z,我想复制/合并 将独立向量中的数据转换成我上面提到的结构数据类型的向量,这样变量将根据结构中的变量对齐。 我可以通过迭代向量的每个成员并分配变量来对此进行归档,但是我正在寻找一种更快更有效的方法,通过一个或两个函数调用将向量的整个范围复制到另一个向量,有没有这样的方法来实现这一点

伪代码:

struct foo
{
vec3 pos;
vec3 norm;
vec2 texCoord;
}

vector<foo> attributes;

vector<vec3> x;
vector<vec3> y;
vector<vec2> z;

copy(x, attributes, offsetof(foo::pos), stride);
copy(y, attributes, offsetof(foo::norm), stride);
copy(z, attributes, offsetof(foo::texCoord), stride);
structfoo
{
vec3位置;
vec3常模;
vec2-texCoord;
}
向量属性;
向量x;
向量y;
向量z;
复制(x,属性,偏移量(foo::pos),跨步);
复制(y、属性、偏移量(foo::norm)、步长);
复制(z,属性,偏移量(foo::texCoord),跨步);

Hm,如果我们知道字节对齐方式,我们可能会做一些低级肮脏的事情

但是如果我们在更高的层次上坚持C++,我们就没有这么多的可能性。 这里有一些例子:

#include <iostream>
#include <vector>
#include <algorithm>
#include <vector>
#include <iterator>


using vec3 = int;
using vec2 = int;

struct foo
{
vec3 pos;
vec3 norm;
vec2 texCoord;
};

int main() {

    std::vector<foo> attributes{};

    std::vector<vec3> x{1,2,3};
    std::vector<vec3> y{4,5,6};
    std::vector<vec2> z{7,8,9};

    // How many elements do we need to copy
    size_t elementsToCopy {std::min({x.size(), y.size(), z.size()})};


    // Solution 1 one. Straight forward. Emplace back and creation of temporary is slow
    for (size_t i = 0; i < elementsToCopy; ++i)
        attributes.emplace_back(foo {x[i],y[i],z[i]});


    // Solution 2. Slight improvement. Set initial size of target vector. Then copy in simple loop. Creation of temporary is slow
    attributes.resize(elementsToCopy);
    for (size_t i = 0; i < elementsToCopy; ++i)
        attributes[i] = std::move(foo ({x[i],y[i],z[i]}));

    // Wrapping in algorithm. But no real improvement. More a less just obfuscation
    std::for_each(attributes.begin(), attributes.end(), [i=0U, &x,&y,&z](foo &f) mutable { return std::move(foo ({x[i],y[i],z[i]}));++i;} );

    for (const auto a : attributes)   
        std::cout << a.pos << " " << a.norm << " " << a.texCoord << "\n";

    return 0;
}
#包括
#包括
#包括
#包括
#包括
使用vec3=int;
使用vec2=int;
结构foo
{
vec3位置;
vec3常模;
vec2-texCoord;
};
int main(){
std::向量属性{};
std::向量x{1,2,3};
std::向量y{4,5,6};
std::向量z{7,8,9};
//我们需要复制多少元素
大小元素复制{std::min({x.size(),y.size(),z.size()});
//解决方案一。直接向前。向后放置,创建临时文件的速度很慢
用于(大小i=0;istd::cout您看到需要的是的树输入变量。这很容易自己实现。@user207421我正在寻找一种无需遍历每个成员的有效方法variable@Some程序员伙计,结构中每个变量的内存对齐情况如何?使用
std::transfo时,我需要担心吗rm
?考虑到您的数据是非相邻的,我怀疑在这种情况下是否有像
memcpy
那样有效的方法。我看不到避免迭代所有3个输入数组的方法。您可以让它在语法上更简单(按照@Someprogrammerdude的建议),但不是算法。您可以选择是按顺序处理3个输入数组(从而遍历输出数组3次),还是交错处理(从而遍历输出数组一次)。后者可能涉及较少的指令,但缓存行为可能会更差,也可能不会更差。如果可能的话,我希望看到低级代码只是为了其他可能感兴趣的人(包括我),那么字节对齐应该是直接的。结构成员分别为12+12+8字节。