Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > const correctness - should C++ prefer const member over non-const?

Reply
Thread Tools

const correctness - should C++ prefer const member over non-const?

 
 
fungus
Guest
Posts: n/a
 
      10-30-2008
I define this class:


class foo {
std::vector<int>data;
public:

int operator[](int n) {
return data[n];
}
int operator[](int n) const {
return data[n];
}
};


Now in my program I do:

foo myFoo;
int x = myFoo[123];
....


Should the const version of foo:perator[] be called?

I think it should, but my compiler disagrees with me.

What's the correct behavior? Why...?



--
<\___/>
/ O O \
\_____/ FTB.

http://www.topaz3d.com/ - New 3D editor!
 
Reply With Quote
 
 
 
 
Jerry Coffin
Guest
Posts: n/a
 
      10-30-2008
In article <7908dabe-5102-4669-bf68-6cd36bedd6a7
@m74g2000hsh.googlegroups.com>, http://www.velocityreviews.com/forums/(E-Mail Removed) says...
> I define this class:
>
>
> class foo {
> std::vector<int>data;
> public:
>
> int operator[](int n) {
> return data[n];
> }
> int operator[](int n) const {
> return data[n];
> }
> };
>
>
> Now in my program I do:
>
> foo myFoo;
> int x = myFoo[123];
> ...
>
>
> Should the const version of foo:perator[] be called?


No.

> I think it should, but my compiler disagrees with me.


The compiler's right. The const version should be called for a const
object. The non-const version should be called for a non-const object.
If you don't/didn't have a non-const version, then the const version
could be called -- but it would be called by convertion the non-const to
a const object first. That's fine (in this case) but it's still a
conversion. When matching overloaded functions, one that doesn't require
a conversion is a better match than one that does require a conversion.

Most people want the const version used on the RHS of an assignment, but
the non-const for the LHS. To get what that kind of behavior, you
normally use a proxy object that overloads operator= and operator T.

--
Later,
Jerry.

The universe is a figment of its own imagination.
 
Reply With Quote
 
 
 
 
fungus
Guest
Posts: n/a
 
      10-30-2008
On Oct 30, 6:31*am, (E-Mail Removed) (blargg) wrote:
>
> I'm interested in why you think it should call the const version. If it
> did, when would it ever call the non-const version?


Ok, maybe I oversimplified it. Supposed operator[]
returns a reference to the int:

int& operator[](int n) {
return data[n];
}
int& operator[](int n) const {
return data[n];
}

If the expression is on the RHS of an assignment, should
the const version be called?


--
<\___/>
/ O O \
\_____/ FTB.

http://www.topaz3d.com/ - New 3D editor!
 
Reply With Quote
 
fungus
Guest
Posts: n/a
 
      10-30-2008
On Oct 30, 10:21*am, fungus <(E-Mail Removed)> wrote:
>
> Ok, maybe I oversimplified it. Supposed operator[]
> returns a reference to the int:
>


....and just before the pedants arrive, suppose it's
a struct not an int, and I want to access a member
of the stuct.

my_struct& operator[](int n) { return data[n]; }
const my_struct& operator[](int n) const { return data[n]; }

Why does the compiler choose the non-const version
for the RHS of an expression...?


--
<\___/>
/ O O \
\_____/ FTB.

http://www.topaz3d.com/ - New 3D editor!

 
Reply With Quote
 
anon
Guest
Posts: n/a
 
      10-30-2008
fungus wrote:
> I define this class:
>
>
> class foo {
> std::vector<int>data;
> public:
>
> int operator[](int n) {
> return data[n];


Changing this line to this:
return data.at(n);
is much safer

> }
> int operator[](int n) const {
> return data[n];
> }
> };
>
>
> Now in my program I do:
>
> foo myFoo;
> int x = myFoo[123];
> ...
>


This should call the non-const operator[]

If you had:
const foo myFoo;
int x = myFoo[123];
then the const version of the operator[] would be used

>
> Should the const version of foo:perator[] be called?
>
> I think it should, but my compiler disagrees with me.
>
> What's the correct behavior? Why...?
>

 
Reply With Quote
 
anon
Guest
Posts: n/a
 
      10-30-2008
fungus wrote:
> On Oct 30, 10:21 am, fungus <(E-Mail Removed)> wrote:
>> Ok, maybe I oversimplified it. Supposed operator[]
>> returns a reference to the int:
>>

>
> ...and just before the pedants arrive, suppose it's
> a struct not an int, and I want to access a member
> of the stuct.
>
> my_struct& operator[](int n) { return data[n]; }
> const my_struct& operator[](int n) const { return data[n]; }
>
> Why does the compiler choose the non-const version
> for the RHS of an expression...?


Because your myFoo object is not const
 
Reply With Quote
 
fungus
Guest
Posts: n/a
 
      10-30-2008
On Oct 30, 6:41*am, Jerry Coffin <(E-Mail Removed)> wrote:
>
> > Should the const version of foo:perator[] be called?

>
> No.
>
> > I think it should, but my compiler disagrees with me.

>
> The compiler's right.


Bummer. I've got an object which triggers quite
a big internal rebuild when you call the non-const
version and I just noticed it's doing a lot of
rebuilding because of this assumption.


--
<\___/>
/ O O \
\_____/ FTB.

http://www.topaz3d.com/ - New 3D editor!
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      10-30-2008
On 30 Okt., 10:59, fungus <(E-Mail Removed)> wrote:
> Bummer. I've got an object which triggers quite
> a big internal rebuild when you call the non-const
> version and I just noticed it's doing a lot of
> rebuilding because of this assumption.


You can explicitly convert your object to a const version if you don't
want the non-const member function to be called in some cases:

const foo& myConstFoo = myFoo;
int blah = myConstFoo[42];

or something like that. static_cast<foo const&>(myFoo)[42] should also
work as far as I can tell. Though, these kinds of casts are still a
bit of a mystery to me.

Cheers,
SG
 
Reply With Quote
 
fungus
Guest
Posts: n/a
 
      10-30-2008
On Oct 30, 11:41*am, (E-Mail Removed) (blargg) wrote:
> I could have sworn "The Design and Evolution of C++"
> covered the reason behind this, but I couldn't find a
> reference.


Maybe you mean section 3.7.1 ?


--
<\___/>
/ O O \
\_____/ FTB.

http://www.topaz3d.com/ - New 3D editor!

 
Reply With Quote
 
fungus
Guest
Posts: n/a
 
      10-30-2008
On Oct 30, 11:45*am, (E-Mail Removed) (blargg) wrote:
> As others have mentioned, a proxy object with an operator T () and
> operator = ( T const& ) would be most transparent to the user.


I don't see how that works for a struct...

I want operator[] to return a reference to a struct
and be able to do this:

Foo f = myStuff[i].foo;

and

myStuff[i].foo = f;


With the first one calling the const version of operator[].



--
<\___/>
/ O O \
\_____/ FTB.

http://www.topaz3d.com/ - New 3D editor!
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
should we prefer deque over vector yancheng.cheok@gmail.com C++ 5 09-14-2006 01:23 PM
Const correctness for pointer data members quantdev2004@yahoo.co.uk C++ 10 10-05-2005 12:09 PM
const-correctness and lambda expression Matthias Kaeppler C++ 1 04-20-2005 10:09 PM
stl list, const correctness Jim Strathmeyer C++ 2 03-20-2005 12:37 AM



Advertisments