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

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

Post by blargg.h4 » Fri, 31 Oct 2008 14:31:29


In article
< XXXX@XXXXX.COM >,



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?
 
 
 

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

Post by Jerry Coff » Fri, 31 Oct 2008 14:41:43

In article <7908dabe-5102-4669-bf68-6cd36bedd6a7
@m74g2000hsh.googlegroups.com>, XXXX@XXXXX.COM says...

No.


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.

 
 
 

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

Post by fungu » Fri, 31 Oct 2008 18:21:33


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.yqcomputer.com/ !
 
 
 

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

Post by fungu » Fri, 31 Oct 2008 18:26:54


....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.yqcomputer.com/ !
 
 
 

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

Post by anon » Fri, 31 Oct 2008 18:41:22


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


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
 
 
 

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

Post by fungu » Fri, 31 Oct 2008 18:59:51


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.yqcomputer.com/ !
 
 
 

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

Post by SG » Fri, 31 Oct 2008 19:29:18


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
 
 
 

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

Post by blargg.h4 » Fri, 31 Oct 2008 19:41:31

In article
< XXXX@XXXXX.COM >,




That's a better question. It chooses the non-const version because C++
doesn't overload based on return type or how the caller uses the return
value, only arguments to the function (including the implicit "this"
argument to member functions). I could have sworn "The Design and
Evolution of C++" covered the reason behind this, but I couldn't find a
reference. I'm assuming it would complicate overloading and often not be
desired.
 
 
 

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

Post by blargg.h4 » Fri, 31 Oct 2008 19:45:23

In article
< XXXX@XXXXX.COM >, SG




But you can't expect users of the class to do this consistently, since
it's quite tedious. Even having a named T& modify( int index ) would be
better. As others have mentioned, a proxy object with an operator T () and
operator = ( T const& ) would be most transparent to the user.
 
 
 

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

Post by fungu » Fri, 31 Oct 2008 20:10:43


Maybe you mean section 3.7.1 ?


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

http://www.yqcomputer.com/ !
 
 
 

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

Post by fungu » Fri, 31 Oct 2008 21:15:43


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.yqcomputer.com/ !
 
 
 

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

Post by fungu » Fri, 31 Oct 2008 22:46:39


This is probably the best solution. I need both const
and non const access inside an event handler function
so I guess I need to make the access more fine-grained.


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

http://www.yqcomputer.com/ !
 
 
 

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

Post by James Kanz » Fri, 31 Oct 2008 23:24:52


It doesn't, really.






There are several solutions. The best would be to find a
compiler modified to allow you to overload operator., and use
that. But that sort of ruins portability. Otherwise, you can
overload operator-> in the proxy, and tell your users to use
that whenever they do a []---it's ugly and counter-intuitive,
but it works. And for special cases, you can define all of the
members in the proxy, so that they forward to the correct member
of owning class. Or you can just require your clients to get a
reference first, e.g.:
Whatever const& rf = myStuff[ i ].foo
Foo f = rf.foo ;

James Kanze (GABI Software) email: XXXX@XXXXX.COM
Conseils en informatique orient objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sard, 78210 St.-Cyr-l'ole, France, +33 (0)1 30 23 00 34
 
 
 

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

Post by blargg.h4 » Sat, 01 Nov 2008 12:46:29

In article
< XXXX@XXXXX.COM >, James



[...]

or

class Stuff {
public:
Whatever const& operator [] ( int ) const;
Whatever& modify( int );
};

void user( Stuff& myStuff )
{
Foo f = myStuff[ i ].foo;
// ...
myStuff.modify( i ).foo = f;
}

If modification is more common than reading, you could instead have [] be
the mutator, and a read( int ) be the accessor.