参加 std::vector C++
Taking part of std::vector C++
在我的代码中有这样的东西:
struct SomeStruct
{
int test1;
int test2;
float test3;
float test4;
};
std::vector<SomeStruct> SomeStructs;
我正在寻找一种方法来以连续的方式获取该向量的一部分,以便我可以使用指针或 c 数组访问它。
假设我想要一个指针来访问结构中的 test2 部分。
我想把vector的那部分传给CAPI,可以吗?
我试图避免创建新的 std::vector/c-array。
它在记忆中的样子(有点):
要以惯用的方式实现这一点,您将需要推出自己的自定义 iterator
,具体 returns 该字段。
看看c++ how to create iterator over one field of a struct vector
C 和 C++ 的互操作性是一个截然不同的问题。为了简化事情,您可能只想在 C 中实现它。
不,你要求的是不可能的。快速回顾:
- 我们可以清楚地看到该结构的 test2 条目当前在内存中没有连续布局,因为它们只是连续结构的一个成员,所以很明显其他结构元素位于每次出现之间测试2.
- 您希望它们是连续的,因此您需要与当前不同的内存布局。
- 您不想创建新的向量或数组,所以您坚持使用当前的内存布局,这是错误的。
你的选择是这样的:
- 将变量更改为 4 个变量向量而不是一个结构向量。
- 需要时创建一个新矢量。
- 不要使用需要连续内存的 C API。
对于 3 值得注意的是一些 C APIs,特别是 BLAS,支持 "strided" 数组,这意味着元素之间有一个固定大小的间隙,这将为您解决这个问题.
如果你想在 for 循环中访问它,你可以这样做:
for (const auto& iterator: SomeStructs)
{
const int& test2 = iterator.test2;
// do what you need to do
}
如果需要第j个元素:
const int& test2 = SomeStructs[j].test2
通过这种方式,您不会制作额外的副本,而是直接从向量中引用项目。如果需要更改值,请删除 const
无法从指针或数组访问每个 test2
的内容,因为 test2
成员在内存中不连续,即使向量中的结构是连续的。结构中还有其他数据,因此您需要跳过它来读取每个 test2
.
当您发现自己在问这样的问题时,请尝试考虑您可以使用的其他数据结构,这些数据结构会使问题更容易解决。对于这种情况,也许 std::unordered_map
会是一个不错的选择。
std::unordered_map<int,SomeStruct> map;
// make a struct...
map.insert(std::make_pair<int,SomeStruct>(a_struct.test2,a_struct));
// add a bunch more structs...
// get an iterator to all the keys in the map (ie. something like a pointer to all test2 members)
key_iterator = map.begin()
如果我能治好你,我认为这是可能的。
struct SomeStruct
{
int test1;
int test2;
float test3;
float test4;
};
int size = 3;// whatever size
vector<SomeStruct> myStruct(size);
myStruct[0].test1 = 0;
myStruct[1].test1 = 1;
myStruct[2].test1 = 2;
/* myPtest1 will allow you to get the test1 part of myStruct in a
contiguous memory manner*/
int *myPtest1 = new int(myStruct.size());
for(int i = 0; i< myStruct.size(); i++)
myPtest1[i] = myStruct[i].test1;
// for illustration.
cout << myPtest1[0] << endl; // 0
cout << myPtest1[1] << endl; // 1
cout << myPtest1[2] << endl; // 2
您现在可以将 myPointer
传递给您的 API,myPointer 只允许您访问 myStruct
向量的 test1
部分。
您可以对其余 SomeStruct
属性执行相同的操作。
在我的代码中有这样的东西:
struct SomeStruct
{
int test1;
int test2;
float test3;
float test4;
};
std::vector<SomeStruct> SomeStructs;
我正在寻找一种方法来以连续的方式获取该向量的一部分,以便我可以使用指针或 c 数组访问它。
假设我想要一个指针来访问结构中的 test2 部分。 我想把vector的那部分传给CAPI,可以吗?
我试图避免创建新的 std::vector/c-array。
它在记忆中的样子(有点):
要以惯用的方式实现这一点,您将需要推出自己的自定义 iterator
,具体 returns 该字段。
看看c++ how to create iterator over one field of a struct vector
C 和 C++ 的互操作性是一个截然不同的问题。为了简化事情,您可能只想在 C 中实现它。
不,你要求的是不可能的。快速回顾:
- 我们可以清楚地看到该结构的 test2 条目当前在内存中没有连续布局,因为它们只是连续结构的一个成员,所以很明显其他结构元素位于每次出现之间测试2.
- 您希望它们是连续的,因此您需要与当前不同的内存布局。
- 您不想创建新的向量或数组,所以您坚持使用当前的内存布局,这是错误的。
你的选择是这样的:
- 将变量更改为 4 个变量向量而不是一个结构向量。
- 需要时创建一个新矢量。
- 不要使用需要连续内存的 C API。
对于 3 值得注意的是一些 C APIs,特别是 BLAS,支持 "strided" 数组,这意味着元素之间有一个固定大小的间隙,这将为您解决这个问题.
如果你想在 for 循环中访问它,你可以这样做:
for (const auto& iterator: SomeStructs)
{
const int& test2 = iterator.test2;
// do what you need to do
}
如果需要第j个元素:
const int& test2 = SomeStructs[j].test2
通过这种方式,您不会制作额外的副本,而是直接从向量中引用项目。如果需要更改值,请删除 const
无法从指针或数组访问每个 test2
的内容,因为 test2
成员在内存中不连续,即使向量中的结构是连续的。结构中还有其他数据,因此您需要跳过它来读取每个 test2
.
当您发现自己在问这样的问题时,请尝试考虑您可以使用的其他数据结构,这些数据结构会使问题更容易解决。对于这种情况,也许 std::unordered_map
会是一个不错的选择。
std::unordered_map<int,SomeStruct> map;
// make a struct...
map.insert(std::make_pair<int,SomeStruct>(a_struct.test2,a_struct));
// add a bunch more structs...
// get an iterator to all the keys in the map (ie. something like a pointer to all test2 members)
key_iterator = map.begin()
如果我能治好你,我认为这是可能的。
struct SomeStruct
{
int test1;
int test2;
float test3;
float test4;
};
int size = 3;// whatever size
vector<SomeStruct> myStruct(size);
myStruct[0].test1 = 0;
myStruct[1].test1 = 1;
myStruct[2].test1 = 2;
/* myPtest1 will allow you to get the test1 part of myStruct in a
contiguous memory manner*/
int *myPtest1 = new int(myStruct.size());
for(int i = 0; i< myStruct.size(); i++)
myPtest1[i] = myStruct[i].test1;
// for illustration.
cout << myPtest1[0] << endl; // 0
cout << myPtest1[1] << endl; // 1
cout << myPtest1[2] << endl; // 2
您现在可以将 myPointer
传递给您的 API,myPointer 只允许您访问 myStruct
向量的 test1
部分。
您可以对其余 SomeStruct
属性执行相同的操作。