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. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    67

    Cool 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. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,157
    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).
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,915
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Feb 2010
    Posts
    67
    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. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,157
    Quote 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

    Quote 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?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Feb 2010
    Posts
    67
    This is probably a sinful answer amongst you guys, but the simplest answer is...

    Because I'm lazy

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,915
    Again, what are you trying to do?
    Sometimes there are even easier and better solutions.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,157
    If you are lazy, then it would be simpler to not want a vector of multiple datatypes, because that will involve more work
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Feb 2010
    Posts
    67

    Cool

    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 hope that made sense.


    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)
    Last edited by CPlus; 08-08-2010 at 04:07 AM.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,915
    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.
    Last edited by Elysia; 08-08-2010 at 04:20 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,157
    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.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Feb 2010
    Posts
    67
    Thank you LaserLight and Elysia for your points. It's true that C++ isn't making this easy .

  13. #13
    Registered User
    Join Date
    Feb 2010
    Posts
    67

    Smile

    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. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,915
    Create appropriate constructors in your struct.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Feb 2010
    Posts
    67

    Question

    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 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 05-18-2010, 05:14 AM
  2. Problem Passing Structure Reference To Function
    By soj0mq3 in forum C Programming
    Replies: 9
    Last Post: 04-24-2010, 11:27 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 07:39 AM
  4. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM
  5. C structure within structure problem, need help
    By Unregistered in forum C Programming
    Replies: 5
    Last Post: 11-30-2001, 05:48 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21