containing one's own type

Discussion in 'C++' started by Christopher, Jul 24, 2008.

  1. Christopher

    Christopher Guest

    Related to my last post, but seperate question

    Can a class be made into a container of its self?


    Could I
    Create an attribute class representing a name, value pair
    Create an attributeGroup class wrapping a map of attributes
    and then add to the attributeGroup class to also wrap a map of
    attributeGroups?

    That way an attributeGroup could contain n levels of attributes?
    Christopher, Jul 24, 2008
    #1
    1. Advertising

  2. Christopher

    Christopher Guest

    On Jul 24, 1:41 pm, Victor Bazarov <> wrote:
    > Christopher wrote:
    > I couldn't get my mind around those English sentences, perhaps you could
    > put it in C++ (don't worry about compilability of your code for now)?
    >
    > V



    Conceptual without error handling considered:

    // Basic name value pair
    class Attribute
    {
    public:
    Attribute();
    ~Attribute();

    const std::string & GetName() const;
    void SetName(const std::string & name);

    template<typename T>
    void SetValue(const T & value)
    {
    // use boost's lexical cast
    }

    template<typename T>
    void GetValue(const std::string & name, T & value_out)
    {
    // use boost's lexical cast
    }

    private:

    std::string name;
    std::string value;
    }

    // Group of name value pairs
    class AttributeGroup
    {
    public:
    AttributeGroup();
    ~AttributeGroup();

    const std::string & GetName() const;
    void SetName(const std::string & name);

    void InsertAttribute(const Attribute & attribute);
    void RemoveAttribute(const std::string & name);
    const Attribute & GetAttribute(const std::string & name) const;

    // Questionable Code
    void InsertAttributeGroup(const AttributeGroup & group);
    void RemoveAttributeGroup(const std::string & name);
    const AttributeGroup & GetAttributeGroup(const std::string & name)
    const;

    private:

    std::string name;

    typedef std::map<std::string, Attribute> AttributeMap;

    // Questionable Code
    typedef std::map<std::string, AttributeGroup> AttributeGroupMap;
    }
    Christopher, Jul 24, 2008
    #2
    1. Advertising

  3. Victor Bazarov wrote:
    > Christopher wrote:
    >> Related to my last post, but seperate question
    >>
    >> Can a class be made into a container of its self?

    >
    > You're asking, can any box contain several boxes of the same size and
    > capacity, right? Not in this universe.


    It depends on your definition of "contain". This is perfectly possible:

    class A
    {
    A* array_of_A[10];

    public:
    void init()
    {
    for(int i = 0; i < 10; ++i)
    array_of_A = new A;
    }
    };
    Juha Nieminen, Jul 24, 2008
    #3
  4. On Jul 24, 2:56 pm, Christopher <> wrote:
    > Related to my last post, but seperate question
    >
    > Can a class be made into a container of its self?


    Of course

    #include <vector>
    class Test {
    int i;
    std::vector<Test> myselfVector;
    };

    int main(int argc, char* argv[])
    {
    Test t;
    }
    Darío Griffo, Jul 24, 2008
    #4
  5. Christopher

    James Kanze Guest

    On Jul 24, 9:45 pm, Darío Griffo <>
    wrote:
    > On Jul 24, 2:56 pm, Christopher <> wrote:


    > > Related to my last post, but seperate question


    > > Can a class be made into a container of its self?


    > Of course


    > #include <vector>
    > class Test {
    > int i;
    > std::vector<Test> myselfVector;
    > };


    Which is undefined behavior, and won't compile with g++.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 24, 2008
    #5
  6. On Jul 24, 5:02 pm, James Kanze <> wrote:
    > On Jul 24, 9:45 pm, Darío Griffo <>
    > wrote:
    >
    > > On Jul 24, 2:56 pm, Christopher <> wrote:
    > > > Related to my last post, but seperate question
    > > > Can a class be made into a container of its self?

    > > Of course
    > > #include <vector>
    > > class Test {
    > >         int i;
    > >         std::vector<Test> myselfVector;
    > > };

    >
    > Which is undefined behavior,


    I didn't know that.
    Where can I find more information? Any paper?

    > and won't compile with g++.


    dario@illusion:~/test$ g++ test.cpp -o showmethemoney
    dario@illusion:~/test$ ls -lh
    -rwxr-xr-x 1 dario dario 8.6K 2008-07-24 17:12 showmethemoney
    -rw-r--r-- 1 dario dario 135 2008-07-24 17:12 test.cpp

    dario@illusion:~/test$ g++ --version
    g++ (Debian 4.3.1-2) 4.3.1
    Darío Griffo, Jul 24, 2008
    #6
  7. Christopher wrote:
    > Conceptual without error handling considered:
    >
    > // Basic name value pair
    > class Attribute

    [...]
    > private:
    >
    > std::string name;
    > std::string value;
    > }


    That is a name-value pair...

    > // Group of name value pairs
    > class AttributeGroup
    > {

    [...]
    > private:
    >
    > std::string name;
    >
    > typedef std::map<std::string, Attribute> AttributeMap;


    That would be a named name-value pair. Huh?

    So AttributeGroup would be a group of named name-value pairs with a name.

    > // Questionable Code
    > typedef std::map<std::string, AttributeGroup> AttributeGroupMap;
    > }


    That would be a named (group of ... with a name).

    Ok, back to the drafting table.

    You need a map which associates names with values. Which would be a
    group of name-value pairs, letting you search for a specific name.
    The value can be either a string, lexical-casted to whatever type you
    want, or a map by itself. Basically this is:

    typedef std::map<std::string, either_string_or_namedGroup> namedGroup;

    For implementing either_string_or_namedGroup, you could use a base class
    with two derived classes, one containing a string and one containing a
    namedGroup, and a nice interface to access those.
    A recursive boost.variant would do as well and would handle the memory
    deallocation issues.

    --
    Thomas
    Thomas J. Gritzan, Jul 24, 2008
    #7
  8. Christopher

    Kai-Uwe Bux Guest

    Darío Griffo wrote:

    > On Jul 24, 5:02 pm, James Kanze <> wrote:
    >> On Jul 24, 9:45 pm, Darío Griffo <>
    >> wrote:
    >>
    >> > On Jul 24, 2:56 pm, Christopher <> wrote:
    >> > > Related to my last post, but seperate question
    >> > > Can a class be made into a container of its self?
    >> > Of course
    >> > #include <vector>
    >> > class Test {
    >> > int i;
    >> > std::vector<Test> myselfVector;
    >> > };

    >>
    >> Which is undefined behavior,

    >
    > I didn't know that.
    > Where can I find more information? Any paper?


    The standard [17.4.3.6/2] last item: you get undefined behavior if you
    instantiate vector<> with an incomplete type.


    >> and won't compile with g++.

    >
    > dario@illusion:~/test$ g++ test.cpp -o showmethemoney
    > dario@illusion:~/test$ ls -lh
    > -rwxr-xr-x 1 dario dario 8.6K 2008-07-24 17:12 showmethemoney
    > -rw-r--r-- 1 dario dario 135 2008-07-24 17:12 test.cpp
    >
    > dario@illusion:~/test$ g++ --version
    > g++ (Debian 4.3.1-2) 4.3.1


    You probably need to build g++ with --enable-concept-checks or something
    like that.

    BTW: this shows that library writers have to do some work to make code
    violating [17.4.3.6/2] actually fail, and it is not hard to implement
    std::vector in such a way that your code will work as expected (in fact, it
    is easier to do so than to do otherwise). Nonetheless, the standard is not
    likely to change with regard to this item; and I think that
    std::shared_ptr<> is the only library component for which an exception will
    be made.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jul 25, 2008
    #8
  9. Christopher

    Kai-Uwe Bux Guest

    Christopher wrote:

    > Related to my last post, but seperate question
    >
    > Can a class be made into a container of its self?


    Yes. I have a pure_finite_set class in my library whose values are the
    finite sets from set theory without atoms. So, something like

    { {}, { {}, {{}} } }

    is a valid value. A pure_finite_set _is_ nothing but a finite set of
    pure_finite_set values.


    > Could I
    > Create an attribute class representing a name, value pair
    > Create an attributeGroup class wrapping a map of attributes
    > and then add to the attributeGroup class to also wrap a map of
    > attributeGroups?
    >
    > That way an attributeGroup could contain n levels of attributes?


    Huh? What is the problem you are trying to solve? It appears that you are
    going down a path of increasing complexity.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jul 25, 2008
    #9
  10. Christopher

    James Kanze Guest

    On Jul 24, 10:16 pm, Darío Griffo <>
    wrote:
    > On Jul 24, 5:02 pm, James Kanze <> wrote:


    > > On Jul 24, 9:45 pm, Darío Griffo <>
    > > wrote:


    > > > On Jul 24, 2:56 pm, Christopher <> wrote:
    > > > > Related to my last post, but seperate question
    > > > > Can a class be made into a container of its self?
    > > > Of course
    > > > #include <vector>
    > > > class Test {
    > > > int i;
    > > > std::vector<Test> myselfVector;
    > > > };


    > > Which is undefined behavior,


    > I didn't know that.
    > Where can I find more information? Any paper?


    The standard. More generally, however, any textbook concerning
    the STL should point out that you're only allowed to instantiate
    it for complete types (which is, in fact, true of every template
    currently in the standard).

    > > and won't compile with g++.

    >
    > dario@illusion:~/test$ g++ test.cpp -o showmethemoney
    > dario@illusion:~/test$ ls -lh
    > -rwxr-xr-x 1 dario dario 8.6K 2008-07-24 17:12 showmethemoney
    > -rw-r--r-- 1 dario dario 135 2008-07-24 17:12 test.cpp


    > dario@illusion:~/test$ g++ --version
    > g++ (Debian 4.3.1-2) 4.3.1


    By default, g++ (like all other compilers I know) doesn't
    implement C++, but rather a somewhat similar, but not identical,
    language. For everyday use, I use "g++ -std=c++98 -pedantic
    -ffor-scope -fno-gnu-keywords -foperator-names -pipe -Wall -W
    -Woverloaded-virtual -Wno-sign-compare -Wno-deprecated
    -Wno-non-virtual-dtor -Wpointer-arith -Wno-unused -Wno-switch
    -Wno-missing-braces -Wno-long-long -static-libgcc -ggdb3
    -D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG
    -D_GLIBCXX_DEBUG_PEDANTIC". (Some of the options represent
    personal preferences, of course, and some correspond to
    constraints due to the code I work with -- -Wno-long-long, for
    example. But as a very minimum, if you're trying to work in
    standard C++, you need -std=c++98 -pedantic
    -D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG
    -D_GLIBCXX_DEBUG_PEDANTIC, and perhaps -ffor-scope
    -fno-gnu-keywords.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 25, 2008
    #10
  11. Christopher

    James Kanze Guest

    On Jul 25, 1:11 am, Kai-Uwe Bux <> wrote:
    > Darío Griffo wrote:


    [...]
    > You probably need to build g++ with --enable-concept-checks or
    > something like that.


    Perhaps -D_GLIBCXX_CONCEPT_CHECKS? (I think that
    --enable-concept-checks is only available in some special
    builds.)

    > BTW: this shows that library writers have to do some work to
    > make code violating [17.4.3.6/2] actually fail, and it is not
    > hard to implement std::vector in such a way that your code
    > will work as expected (in fact, it is easier to do so than to
    > do otherwise). Nonetheless, the standard is not likely to
    > change with regard to this item;


    Actually, I think it will change: since concepts are being added
    (I hope), instead of undefined behavior, the error will require
    a diagnostic.

    > and I think that std::shared_ptr<> is the only library
    > component for which an exception will be made.


    For the moment, that's what I understand as well. (Although
    some other constraints are also being loosened: std::list won't
    require Assignable, if I'm not mistaken.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 25, 2008
    #11
  12. On Jul 25, 9:06 am, James Kanze <> wrote:
    > On Jul 24, 10:16 pm, Darío Griffo <>
    > wrote:
    >
    > > On Jul 24, 5:02 pm, James Kanze <> wrote:
    > > > On Jul 24, 9:45 pm, Darío Griffo <>
    > > > wrote:
    > > > > On Jul 24, 2:56 pm, Christopher <> wrote:
    > > > > > Related to my last post, but seperate question
    > > > > > Can a class be made into a container of its self?
    > > > > Of course
    > > > > #include <vector>
    > > > > class Test {
    > > > >         int i;
    > > > >         std::vector<Test> myselfVector;
    > > > > };
    > > > Which is undefined behavior,

    > > I didn't know that.
    > > Where can I find more information? Any paper?

    >
    > The standard.  More generally, however, any textbook concerning
    > the STL should point out that you're only allowed to instantiate
    > it for complete types (which is, in fact, true of every template
    > currently in the standard).
    >
    > > > and won't compile with g++.

    >
    > > dario@illusion:~/test$ g++ test.cpp -o showmethemoney
    > > dario@illusion:~/test$ ls -lh
    > > -rwxr-xr-x 1 dario dario 8.6K 2008-07-24 17:12 showmethemoney
    > > -rw-r--r-- 1 dario dario  135 2008-07-24 17:12 test.cpp
    > > dario@illusion:~/test$ g++ --version
    > > g++ (Debian 4.3.1-2) 4.3.1

    >
    > By default, g++ (like all other compilers I know) doesn't
    > implement C++, but rather a somewhat similar, but not identical,
    > language.  For everyday use, I use "g++ -std=c++98 -pedantic
    > -ffor-scope -fno-gnu-keywords -foperator-names -pipe -Wall -W
    > -Woverloaded-virtual -Wno-sign-compare -Wno-deprecated
    > -Wno-non-virtual-dtor -Wpointer-arith -Wno-unused -Wno-switch
    > -Wno-missing-braces -Wno-long-long -static-libgcc -ggdb3
    > -D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG
    > -D_GLIBCXX_DEBUG_PEDANTIC".  (Some of the options represent
    > personal preferences, of course, and some correspond to
    > constraints due to the code I work with -- -Wno-long-long, for
    > example.  But as a very minimum, if you're trying to work in
    > standard C++, you need -std=c++98 -pedantic
    > -D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG
    > -D_GLIBCXX_DEBUG_PEDANTIC, and perhaps -ffor-scope
    > -fno-gnu-keywords.)



    Thanks a lot James, and also Kai-Uwe Bux for the complete explanation.
    It's that every day we learn new things.
    Darío
    Darío Griffo, Jul 25, 2008
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Randall Parker
    Replies:
    0
    Views:
    1,632
    Randall Parker
    Dec 4, 2005
  2. Stefan Siegl
    Replies:
    1
    Views:
    769
  3. Saverio M.
    Replies:
    0
    Views:
    509
    Saverio M.
    Jul 3, 2006
  4. ujjc001
    Replies:
    0
    Views:
    678
    ujjc001
    Jul 25, 2007
  5. Nate Eldredge

    Initializing compound type containing opaque type

    Nate Eldredge, Oct 1, 2008, in forum: C Programming
    Replies:
    23
    Views:
    785
    David Thompson
    Oct 13, 2008
Loading...

Share This Page