const overload

N

NKOBAYE027

Hi Everyone:

Short description first

MathematicalSet is to be a class template that's supposed to behave as the
name suggests. It has functions that define union, contains,
is_contained_in, etc... I want the thing to behave like a normal collection
as well. That is to comply with the ansi standard for STL collections even
though it manages two separate lists and two statics (universe and null).
The first collection is an object pool within which we store copies of the
objects the user wants in his/her set each wrapped in a 'countable' element
template. The next collection is a list of countable pointers that point to
these elements in the pool. The idea being that we should only need one
distinct copy of each object from which we can build as many sets as we want
which contain that object (or copies of it) in the form of counted pointers.
Then, if the iterator for the MathematicalSet template is defined properly,
we can hand the user her/his set of counted pointers but it will behave as
if it were a set of actual objects instead. Now I've got some code written
towrd this end and it even seems to be working properly. That is, I can
declare and initialise a MathematicalSet::const_iterator and set it to the
beginning of the set...iterate over the set and dereference the iterator to
obtain the const reference to the object i desire. Any code that tries to
modify that object is flagged by the compiler at compile time as faulty. And
the same for MathematicalSet::iterator except, of course, I can have code
that modifies the object pointed to by the iterator. My problem lies in how
the compiler is behaving with regard to the various access functions for the
iterators. Namely the 'begin' function. I checked in the STL def'n of
<list> used by the compiler for direction on how to define my template and
found complementary def'ns of begin() for each iterator type (const and
nonconst) and they look something like this (Note I've removed various _'s
and other decorations for readability):

iterator begin()
{
return (iterator(Acc::Next(Head)));
}

const_iterator begin() const
{
return (const_iterator(Acc::Next(Head)));
}

so I happily set about defining my own 'begin' functions which return
iterators pointing to the beginning of my list of counted pointers in
keeping with the ideas described above. e.g.

template<object>
class MathematicalSet
{
....
class const_iterator{ // stuff }; // end const_iterator
class iterator : public const_iterator { // more stuff }; // end
iterator
.....
// access functions
iterator begin()
{
Set::iterator theStartOfTheSet = m_TheSet.begin();
return (iterator(theStartOfTheSet));
}

const_iterator begin() const
{
Set::const_iterator theStartOfTheSet = m_TheSet.begin();
return (const_iterator(theStartOfTheSet));
}
.....
and now I can write the following code....Note that class bob is just a
silly test class with an int and a char member (see way below for it's
decl'n/def'n if you need to)

int main()
{
bob b, b1, b2;
b2.a = 1;
MathematicalSet<bob> aSet;

aSet.add(b);
aSet.add(b);
aSet.add(b2);
aSet.add(b1);
MathematicalSet< bob >::const_iterator it = aSet.begin();
bob c = *it;
// (*it).a =7; /* note that this line won't compile if uncommented as it is
a const_iterator */
++it;
it++;
--it;
it--;
it++, it++;
c = *it;
MathematicalSet< bob >::iterator itt = aSet.begin();
++itt, ++itt;
itt->a = 3; /* this works fine since itt is nonconst */
bob d = *itt;
return 0;
}

compiles with no errors or warnings and works splendidly, but when I step
through the code I expect to
step through both versions of the begin() function. It doesn't do this at
all, in fact it completely
ignores the const_iterator begin() const function which I expect to be
called for the first
iterator declaration. It actually moves any breakpoints I set in the
function to the 'next valid line' which
is outside of th function, according to the compiler....so....what's wrong
with my thinking? Any comments
or suggestions on this problem (or anything at all) are welcome.

MSVC 6.0 is the compiler though not certain at all if this is the issue.

decl'n/def'n of the silly test class

class bob
{
public:

int a;
char b;

bob():a(0),b(0){}

bob(const bob& d)
{
a = d.a;
b = d.b;
}

bob& operator=(const bob& d)
{
if(this != &d)
{
a = d.a;
b = d.b;
}
return *this;
}

const bool operator==(const bob& d) const
{
return (a == d.a) ? ( b == d.b) : false;
}

~bob(){}
};

thanks, and regards,
L.
 
J

John Harrison

NKOBAYE027 said:
Hi Everyone:

[snip]


int main()
{
bob b, b1, b2;
b2.a = 1;
MathematicalSet<bob> aSet;

aSet.add(b);
aSet.add(b);
aSet.add(b2);
aSet.add(b1);
MathematicalSet< bob >::const_iterator it = aSet.begin();
bob c = *it;
// (*it).a =7; /* note that this line won't compile if uncommented as it is
a const_iterator */
++it;
it++;
--it;
it--;
it++, it++;
c = *it;
MathematicalSet< bob >::iterator itt = aSet.begin();
++itt, ++itt;
itt->a = 3; /* this works fine since itt is nonconst */
bob d = *itt;
return 0;
}

compiles with no errors or warnings and works splendidly, but when I step
through the code I expect to
step through both versions of the begin() function. It doesn't do this at
all, in fact it completely
ignores the const_iterator begin() const function which I expect to be
called for the first
iterator declaration. It actually moves any breakpoints I set in the
function to the 'next valid line' which
is outside of th function, according to the compiler....so....what's wrong
with my thinking? Any comments
or suggestions on this problem (or anything at all) are welcome.

OK, you've misunderstood how function overloading works. The return type of
a function is *never* taken into account when deciding which version of an
overloaded function is called. So that fact that you are assigning to a
const_iterator is completely irrelevant to this situation. What counts is
whether the aSet object is const or not. In this case it isn't so the
non-const version of begin is called, returning an iterator, which is them
implicitly converted (in some way I didn't look) to a const_iterator.

This is all correct and as expected. If you did some experimentation with
other STL iterators you would see that they behave in the same way.

John
 
N

NKOBAYE027

Thanks John. So the object doing the calling is the deciding factor
here...const objects would call the const overloaded function presumably
because of the trailing const in the function declaration? Grrrrrr ok...back
to Stroustrup....


John Harrison said:
NKOBAYE027 said:
Hi Everyone:

[snip]


int main()
{
bob b, b1, b2;
b2.a = 1;
MathematicalSet<bob> aSet;

aSet.add(b);
aSet.add(b);
aSet.add(b2);
aSet.add(b1);
MathematicalSet< bob >::const_iterator it = aSet.begin();
bob c = *it;
// (*it).a =7; /* note that this line won't compile if uncommented as it is
a const_iterator */
++it;
it++;
--it;
it--;
it++, it++;
c = *it;
MathematicalSet< bob >::iterator itt = aSet.begin();
++itt, ++itt;
itt->a = 3; /* this works fine since itt is nonconst */
bob d = *itt;
return 0;
}

compiles with no errors or warnings and works splendidly, but when I step
through the code I expect to
step through both versions of the begin() function. It doesn't do this at
all, in fact it completely
ignores the const_iterator begin() const function which I expect to be
called for the first
iterator declaration. It actually moves any breakpoints I set in the
function to the 'next valid line' which
is outside of th function, according to the compiler....so....what's wrong
with my thinking? Any comments
or suggestions on this problem (or anything at all) are welcome.

OK, you've misunderstood how function overloading works. The return type of
a function is *never* taken into account when deciding which version of an
overloaded function is called. So that fact that you are assigning to a
const_iterator is completely irrelevant to this situation. What counts is
whether the aSet object is const or not. In this case it isn't so the
non-const version of begin is called, returning an iterator, which is them
implicitly converted (in some way I didn't look) to a const_iterator.

This is all correct and as expected. If you did some experimentation with
other STL iterators you would see that they behave in the same way.

John
 
J

John Harrison

NKOBAYE027 said:
Thanks John. So the object doing the calling is the deciding factor
here...const objects would call the const overloaded function presumably
because of the trailing const in the function declaration? Grrrrrr ok...back
to Stroustrup....

Right, or a when you have a const reference. In that case the const overload
would be called as well.

john
 

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,780
Messages
2,569,611
Members
45,266
Latest member
DavidaAlla

Latest Threads

Top