Wednesday, April 6, 2011

Is it possible (or ok) to have a std::list of std::list's?

I have a std::list of Points (that simply store an x, y). Each one of these points represents a polygon, which I later draw.

class Point {
public:
    int x, y;
    Point(int x1, int y1)
    {
        x = x1;
        y = y1;
    }
};

std::list <Point> currentPolygon;

I would like to have a list of these polygons (lists themselves).

Is this possible? How do I have a std::list of a list of Points (so I can store more than one polygon).

From stackoverflow
  • It sure is. But what you probably want - for expandability purposes later - create a second class - "polygon", that holds a list of points. Then use a list of polygons.

    EDIT: I'm no C++ programmer, so I'm sure an implementation like j_random_hacker's response is better if you're needing this for a real project. I merely wanted to give a quickie code example of this design.

    class Point {
    public:
        int x, y;
        Point(int x1, int y1)
        {
            x = x1;
            y = y1;
        }
    };
    
    class Polygon {
    public:
        std::list <Point> currentPolygon;
        Polygon(std::list <Point> p1)
        {
            currentPolygon = p1
        }
    };
    
    Kevin Loney : std:list overloads the assignment operator so yes that will work.
    Jeffrey : Sweet... I've been living too long in the .net arraylist and hashtable world.
    j_random_hacker : Basically OK but I'm -1ing you since you're employing several bad habits: (1) You should declare your Polygon ctor "explicit" to avoid implicit conversions from list; (2) pass p1 by const ref to the ctor; (3) Point and Polygon ctors should both initialise members using an initialiser list.
    Jeffrey : Sounds fair enough. Feel free to edit if the link isn't sufficient enough. I see you have the rep ;-)
    j_random_hacker : @Jeffrey: Thanks for that. I prefer not to edit others' answers to change the meaning of what they wrote, I just fix typos etc. (And insert the odd "j_random_hacker RULZ!!!11!1" :-P)
  • You could use this:

    std::list< std::list<Point> > polygons;
    

    To make things easier, use typedefs.

    class Point {
    public:
        int x, y;
        Point(int x1, int y1)
        {
            x = x1;
            y = y1;
        }
    };
    typedef std::list<Point> PolygonType;
    typedef std::list<PolygonType> PolygonsType;
    
    Calyth : don't forget the space between > and > in std::list >, or the parser would think you want to do a right shift and complain.
  • Here is Jeffrey's code again, tidied up slightly to fix what I was whingeing about in the comments :)

    class Point {
    public:
        int x, y;
        Point(int x1, int y1) : x(x1), y(y1)
        {
        }
    };
    
    class Polygon {
    public:
        std::list <Point> currentPolygon;    // Consider making this private.
        explicit Polygon(std::list <Point> const& p1) : currentPolygon(p1)
        {
        }
    };
    

    [EDIT: Thanks to Matt Davis for pointing out that the user-defined copy constructor I provided was unnecessary, which simplifies things.]

    Matt Davis : Unless I'm not remembering the Scott Meyers "Effective C++" correctly, the compiler provides the copy constructor as well.
    j_random_hacker : @Matt Davis: You're right, I've now fixed this. (For some reason I thought maybe compiler auto-generation of copy ctors might be turned off by providing any 1-parameter ctor of your own, but of course that parameter has to be a (possibly const and/or volatile) reference to the class's own type.)

0 comments:

Post a Comment