Reputation: 231
I have been using vectors but only for the convenience of resizing which they offer. Today, I realized that I do not understand std::vector fully. I have created a data structure needed for my program. It is defined as:
vector<vector<string>, int> memtable;
// the idea is that an element of this vector is something like {[var_name, var_type], loc}
// where the braces and parentheses just refer to a box
I want a memtable where I store information about a variable and its location.
Is my implementation using the vector an acceptable solution and am I able to visualize the container properly?
How do I construct an element of this vector and insert it into the vector (say using vector.push_back()
)?
Elaborating my data-structure, I am creating a memory table which stores the variable, its type, and its location. Since std::vector only allows two types in its type declaration vector<type1, type2>
, I used the solution in the first code snippet. Is the solution below also valid?
vector<string [2], int> memtable; // does this match this container structure -> {[var_name, var_type], loc}
Upvotes: 0
Views: 54
Reputation: 4076
A std::vector has two template parameters, the 1st (T) being compulsary (the type of the value contained) and the 2nd (Allocator) (not compulsary) the allocator type that is used to provider memory for the 1st (T). Note that a vector is a sequence of values of type T (is is not a sequence of types).
The prerequisites for type T is that it shall be CopyAssignable and CopyConstructable, and depending on operations, also Erasable. std::vector is in effect almost like an array of type T, with the difference that it's size is not known upfront, and for this reason it typically embeds an pointer to the actual array and manages access to that via an interface that performs the indirection.
In your case, what you want is to define a type T that suits your requirements:
struct MyType {
std::string name_;
std::string type_;
int location_;
};
... or whatever it is that represents your type. Note that above type meets the requirements by virtue of the fact that the contained types meet all the requirements (*see note). Your vector would then become:
std::vector<MyType> myVector;
... or you could "typify" it by providing a typedef:
typedef std::vector<MyType> MyVector;
MyVector myVector; //instantiate my type.
Note: If the type that you've created contains pointers (indirection), it would still adhere to the requirements (as pointers are builtin types), but it would become dangerous if they manage the pointed to memory themselves (as during assignment and copy construction the source object ends up going out of scope and deleting the memory now contained in the destination (that is present in the container)). In that case you would need to provide/implement the necessary member functions. Fortunately your's doesn't need to.
Finally, what you might also be looking for is a vector of tuple, where tuple represents a sequence of types (as opposed to sequence of values). You could therefore also do this to achieve the same thing:
typedef std::vector<std::tuple<string,string,int>> MyVector;
MyVector myVector;
myVector.push_back(std::make_tuple("Hallo", "Apple", 20));
Upvotes: 1
Reputation: 22084
A std::vector
is similar to an array, so it can hold multiple items, but all of them have to be of the same type.
If you want to store multiple elements in a vector, you need to create a class
or a struct
.
I would recommend to use an enum
for your type as this is more descriptive to read.
enum VarType
{
TYPE_INT
};
class Var
{
public:
Var(std::string name, VarType type)
: var_name(name)
, var_type(type)
{
}
std::string var_name;
VarType var_type;
};
std::vector<Var> vars;
vars.push_back(Var("name", TYPE_INT));
std::cout << "Name: " << vars[0].var_name << std::endl;
Upvotes: 0