how to create a std::vector without knowing the type of data that is in it?

Started by
4 comments, last by jpetrie 13 years, 12 months ago
I got a wierd situation, I want to bea ble to create an instance of a class that has a std::vector inside it, but the class it's self never knows what the actualy value is that's in the vector, just the sizeof the data type. Is this possible?


struct MyStruct
{
    ...
};

class MYClass
{
    std::Vector<UnknownType> myVector;
}


Ultimately I want the vector to contain the MyStruct, but Mystruct can be anything. How would I define the class and be able to create the class so the vector would work normally? The reason I'm trying to do this is for my 2D renderer, I've always used a single vertex type for everything, but I've recently had the need for multiple types of vertex's some the difference only being the lack of extra data such as multiple uv coordinates or some needing color values other not. So I'm trying to figure out a way to allow for multiple types without having to hard code them into the way I sort through and process drawcalls.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Advertisement
No, vector doesn't work like that. There may be some boost function that can give you that kind of behavior, but not for standard vector.

If you want to include multiple types of object in a vector, you can do it through polymorphism, with the constraint that all members inherit from a base class, and that the vector only stores pointers to objects (and not the objects themselves). For example you can do this:

class A : public BaseClass {...}class B : public BaseClass {...}std::vector<BaseClass*> vec;A* a = new A();B* b = new B();BaseClass* c = new BaseClass();vec.push_back(a);vec.push_back(b);vec.push_back(c);



But you cannot just push any old thing you want into a vector.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
Quote:Original post by karwosts
No, vector doesn't work like that. There may be some boost function that can give you that kind of behavior, but not for standard vector.

If you want to include multiple types of object in a vector, you can do it through polymorphism, with the constraint that all members inherit from a base class, and that the vector only stores pointers to objects (and not the objects themselves). For example you can do this:

*** Source Snippet Removed ***


But you cannot just push any old thing you want into a vector.


That was my first thought, but I'l constantly be rebuilding the data inside the vector, and haveing to allocate memory for every element each frame seems like it would be a big hit to speed.

going with that idea though if I have a function that takes a pointer to the base class would I be able to do this.

MyFunction(baseClass*);// call it like soMyFunction(new derivedClass(...));
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Quote:
That was my first thought, but I'l constantly be rebuilding the data inside the vector, and haveing to allocate memory for every element each frame seems like it would be a big hit to speed.

Forgetting for the moment if this is a true statement (it should not be, you're probably doing something wrong)... it has nothing to do with what type the vector uses, so it's a non-issue. Runtime polymorphic objects, as suggested, are what you want here -- vectors are templates, templates are compile-time concepts in C++.

Quote:
going with that idea though if I have a function that takes a pointer to the base class would I be able to do this.

Yes.
Well consider I have a list of pointers. That frame I'll use the data that is in them, then set them as 'used', and have to use 'delete' on them to free the memory. on the next frame I just start from the bottom of the list and begin to create new data ofcourse using the old pointers. I never delete the vector, but I do want to change everything that is in the vector.

The other idea I had that would go along with this, but i can't figure out how to make it work easily with one function call.

store an iterator to the list and only call 'new' when I actually have to push a pointer onto the stack, otherwise I just change the data that is in the created struct. That seems like the best way to go about it, but the problem is how to do it in one function?

if My function is

MyFunction(structPointer* sp);

how would I changed that to work with the idea?

Should I specify a size for the vector when creating the class and just create a bunch of blank structs ie

for (0 to maxSize)
push_back(new struct(...))

Then once again how do I define a function that can take the derived class as an argument without really know what it is, and be able to set the desired struct with the variables from the argument?
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Quote:
Well consider I have a list of pointers. That frame I'll use the data that is in them, then set them as 'used', and have to use 'delete' on them to free the memory. on the next frame I just start from the bottom of the list and begin to create new data ofcourse using the old pointers. I never delete the vector, but I do want to change everything that is in the vector.

Whether or not this is a problem depends on your requirements. If you do not require polymorphic behavior from the vector elements, do not store pointers-to-T, just store T. This will reduce the allocation thrashing you require down to what the vector does itself, which can be optimized by reusing the space, and the cost is basically that of your ctors/dtors.

If you do require polymorphic behavior you cannot avoid the pointers (since you cannot store references in SC++L containers) and thus cannot avoid the allocation unless the pointers are non authoritative (stored elsewhere) -- which is a viable option.

Quote:
The other idea I had that would go along with this, but i can't figure out how to make it work easily with one function call.

store an iterator to the list and only call 'new' when I actually have to push a pointer onto the stack, otherwise I just change the data that is in the created struct. That seems like the best way to go about it, but the problem is how to do it in one function?

if My function is

MyFunction(structPointer* sp);

how would I changed that to work with the idea?

Should I specify a size for the vector when creating the class and just create a bunch of blank structs ie

for (0 to maxSize)
push_back(new struct(...))

Then once again how do I define a function that can take the derived class as an argument without really know what it is, and be able to set the desired struct with the variables from the argument?

This is all wonderfully useless information and conjecture... relatively speaking. It will be more useful for you to describe the problem you want to solve in high level terms, rather than the solution you think you need.

You've specified thus far that this has something to do with vertices in a 2D renderer. Explain in more detail; what do you want to do with these vertices, how do you want to handle them? Then we'll be able to provide better guidance.

This topic is closed to new replies.

Advertisement