# Vector of Structure

This is a discussion on Vector of Structure within the C++ Programming forums, part of the General Programming Boards category; Hello Is there any way to do this? (Green is working code, Red is non-working code) Code: int main() { ...

1. ## Vector of Structure

Hello

Is there any way to do this?
(Green is working code, Red is non-working code)

Code:
```int main()
{

struct INT_STR{
int i;
string s;
};

INT_STR a;
INT_STR b;

a.i = 123;
b.s = "abc";

//Everything above works

//Things get buggy below
vector<INT_STR> c;  //I also tried vector<struct>, but thought it was strange since it would not refer to a specific structure this way
c.push_back(a.i);  //adds 123 to vector c
c.push_back(b.s);  //adds "abc" to vector c

cout << c.at(0) << "," << c.at(1);

//On the console, we'd see
//123,abc

}```
Thanks

2. It looks like you are thinking of doing something like this:
Code:
```#include <string>
#include <ostream>

struct IntStr {
IntStr(int i, const std::string& s) : i(i), s(s) {}

int i;
std::string s;
};

std::ostream& operator<<(std::ostream& out, const IntStr& x)
{
return out << x.i << ',' << x.s;
}

#include <vector>
#include <iostream>

int main()
{
using namespace std;

vector<IntStr> c;
c.push_back(IntStr(123, "abc"));

cout << c.at(0) << endl;
//On the console, we'd see
//123,abc
}```
Notice the addition of a constructor with initialisation list, and the overloading of operator<<, and then the use of the constructor to push an IntStr object to the back of the vector. Oh, I renamed INT_STR to IntStr as fully capitalised names are more conventionally reserved for macro names (or more generally, names of constants).

3. Code:
```    c.push_back(a.i);  //adds 123 to vector c
c.push_back(b.s);  //adds "abc" to vector c```
Since your vector is of type IntStr, you may push back IntStr, not integers or strings. That's your problem.
You could also modify laserlight's example to create two constructors: one for strings and one for integers, then modify appropriate data member.
Remember to create a new struct and initialize it with what you want before you push it back.

4. Looking at this portion:
Code:
```    c.push_back(IntStr(123, "abc"));

cout << c.at(0) << endl;```
Is there any way to extract IntStr's individual parameters?

For example:
(I'm going to use faulty notation here, but it will look familiar enough to understand its logic):
Code:
```    c.push_back(IntStr(123, "abc"));
cout << c.at(0)[0] << endl;
cout << c.at(0)[1] << endl;```
Result:
123
abc

Is it possible to have a vector of multiple datatypes?
This method would be messy, but if the above is possible, this vector could be made doing

Code:
```    c.push_back(IntStr(123, ""));
c.push_back(IntStr(0, "String1"));
c.push_back(IntStr(0, "String2"));
c.push_back(IntStr(456, ""));

cout << c.at(0)[0] << endl; //accessing integer portion of first element
cout << c.at(1)[1] << endl; //accessing string portion of second element
cout << c.at(2)[1] << endl; //accessing string portion of third element
cout << c.at(3)[0] << endl; //accessing integer portion of fourth element```
using 0 and "" as default values.

The downside to this method is the wasted space these default values are using up. Still, a working version is better than no version. Until I can find some better method, this should do.

I guess the other method would be to make a vector of strings and convert the elements to int, float, etc.
when needed.

5. Originally Posted by CPlus
Is there any way to extract IntStr's individual parameters?
Yes, e.g., c.at(0).i and c.at(0).s

Originally Posted by CPlus
Is it possible to have a vector of multiple datatypes?
In a way (or perhaps a few ways), yes, but why exactly do you want to do this?

6. This is probably a sinful answer amongst you guys, but the simplest answer is...

Because I'm lazy

7. Again, what are you trying to do?
Sometimes there are even easier and better solutions.

8. If you are lazy, then it would be simpler to not want a vector of multiple datatypes, because that will involve more work

9. Yeah you both have good points there.

To be honest, I don't actually have any concrete projects in mind. I'm trying to learn many ways to go about doing things in case I need them in the future (I'm writing self-tutorials as I learn things).

I think this specific case is similar to writing a function.
Writing the function does require work at first, but then it becomes callable at any future point in the program, which ends up making source code more readable (if the function has a very indicative name anyway).

I was hoping this would be the case (getting the definitions out of the way in the beginning of the program and then using this method throughout the program, just like you would call a function).

I'm sure that it would look very different in the way the circuitry actually handles it, but visually, I was hoping to go for something like

Code:
```vector<any_datatype> AnyVec;
AnyVec.push_back(0);
AnyVec.push_back(1.0);
AnyVec.push_back('a');
AnyVec.push_back("Hello");```
I doubt the end result will even look that pretty. But it would still be useful, I'm sure.

So far the easiest method I can think of would be to make a vector<string> and convert the elements as need be.
I don't know if that method would have drawbacks though (maybe the conversions would make it temporally disadvantageous)

10. However, just as a function does one thing and accepts a specific number of arguments of specific types, so does a vector.
The only problem I can see is that you can't overload vectors like you can functions.
But this shouldn't be a problem, because a vector stores one type of information just as one function handles of type of problem.
While doing what you want is possible, it begs the question of how you should access the data later. I don't think it will be very useful. I think it will hurt efficiency.

You're also going against the principles of C++ here: C++ is a statically typed language. It was built to maintain the type at compile time.
What you're suggesting means that the type would have to be derived at runtime. While possible, it may be difficult, since C++ wasn't exactly built around this principle or paradigm.

11. Well, if you really do want examples of this sort of thing, look at Boost.Any and Boost.Variant. There is also the option of creating a class hierarchy and then having a vector of (smart) pointers to the base class.

12. Thank you LaserLight and Elysia for your points. It's true that C++ isn't making this easy .

13. Is there any way to do this?

Code:
```#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct IntStr
{
int i;
string s;
vector<IntStr> v;
};

int main()
{
IntStr temp;
temp.i = 123;
temp.s = "abc";

//Errors begin here
temp.v.push_back(789);
temp.v.push_back("xyz");
cout << temp.v.at(0) << endl;
cout << temp.v.at(1) << endl;
}```
Errors are in italics.
How do I access the vector portion of temp?

Compiler analysis

no matching function for call to `std::vector<IntStr, std::allocator<IntStr> >:: push_back(int)'

candidates are: void std::vector<_Tp, _Alloc>:: push_back(const _Tp&) [with _Tp = IntStr, _Alloc = std::allocator<IntStr>]

Thanks

14. Create appropriate constructors in your struct.

15. Oh okay. This is where I'm lost. I don't know much about structures aside from their class-like nature.
I don't know how to use constructors, but would a constructor look like this?

Code:
```struct IntStr
{
IntStr(vector<IntStr> *v)
private:
int i;
string s;
vector<IntStr> v;
};

IntStr::IntStr(vector<IntStr> *v)
{
//???
}```
This is where I got lost, as I don't know what it is I'm supposed to be constructing (or if the syntax is even right).

Page 1 of 3 123 Last