containing one's own type

C

Christopher

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?
 
C

Christopher

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;
}
 
J

Juha Nieminen

Victor said:
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;
}
};
 
D

Darío Griffo

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;
}
 
D

Darío Griffo

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
 
T

Thomas J. Gritzan

Christopher said:
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.
 
K

Kai-Uwe Bux

Darío Griffo said:
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
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
 
K

Kai-Uwe Bux

Christopher said:
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
 
J

James Kanze

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).
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.)
 
J

James Kanze

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.)
 
D

Darío Griffo

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).



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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top