Reputation: 361
In my code I have something like this:
struct SomeStruct
{
int test1;
int test2;
float test3;
float test4;
};
std::vector<SomeStruct> SomeStructs;
I am looking for a way to get a part of that vector in a continues manner, So that I can access it with a pointer or a c-array.
Suppose I want a pointer to access only the part of the struct that are test2. I want to pass that part of the vector to a C API, Is it possible?
I'm trying to avoid creating a new std::vector/c-array.
How It look's like in memory(kind of):
Upvotes: 2
Views: 234
Reputation: 673
If i got you well, i think its possible.
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
You can now pass myPointer
to your API, myPointer gives you access to only test1
part of myStruct
vector.
you can do same for the rest of the SomeStruct
attributes.
Upvotes: 0
Reputation: 2154
To implement this in an idiomatic manner you will need to roll your own custom iterator
that returns that field specifically.
Take a look at c++ how to create iterator over one field of a struct vector
C and C++ interoperability is a vastly different problem. To simplify things you may just want to implement it in C.
Upvotes: 0
Reputation: 1705
There's no way to access just the contents of each test2
from a pointer or array, because the test2
members are not contiguous in memory even if the structs in the vector are. There's other data in the struct, so you need to skip over that to read each test2
.
When you find yourself asking a question like this, try thinking about other data structures you can use that would make the problem easier to solve. For this case, perhaps a std::unordered_map
would be a good choice.
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()
Upvotes: 0
Reputation: 359
If you want to access it in a for loop you can do:
for (const auto& iterator: SomeStructs)
{
const int& test2 = iterator.test2;
// do what you need to do
}
If you need the j-th element:
const int& test2 = SomeStructs[j].test2
In this way you are not making extra copies but you are directly referencing items from vector. Remove const if you need to change the value
Upvotes: -1
Reputation: 17704
No, what you are asking for is impossible. Quick review:
Your options are like so:
For 3 it is worth noting that some C APIs, notably BLAS, supported "strided" arrays which means that there is a fixed size gap between elements, which would solve this issue for you.
Upvotes: 4