pre/post increment/decrement return type?

A

Angel Tsankov

Should pre/post increment/decrement return const or non-const?
What about other functions?
 
K

Kai-Uwe Bux

Ian said:
Non-const, otherwise the expression can't be an lvalue.

Why would you want, e.g., iter++ to be an lvalue? Also, the standard
specified the following requirements for iterators:

++r returns &X (X being the type of the iterator)
r++ returns something convertible to X const &

[snip]


Best

Kai-Uwe Bux
 
V

Victor Bazarov

Angel said:
Should pre/post increment/decrement return const or non-const?
What about other functions?

Totally up to you. While the behaviour of pre- and post-increment
is somewhat expected, based on the behaviour of the built-in types,
'other functions' are certaintly not. And even then, if you are
the one who designs and implements pre- and post-increments for
your UDTs, you're free to make them do what you please. For all
we care, they can all return 'void'. Do as your model dictates.
There is no good enough general rule.

V
 
I

Ian Collins

Kai-Uwe Bux said:
Ian Collins wrote:




Why would you want, e.g., iter++ to be an lvalue? Also, the standard
specified the following requirements for iterators:
You're right, I probably wouldn't, but ++iter could be if you wanted to
assign something to the result,

*(++i) = x;

where i is some type with const and non-const operator*().

Then again, if iter were some form of smart pointer, one might want to write

*(i++) = x;

because it's valid for normal pointers. Make sense, or am I lacking
caffeine?
 
K

Kai-Uwe Bux

Ian said:
You're right, I probably wouldn't, but ++iter could be if you wanted to
assign something to the result,

*(++i) = x;

where i is some type with const and non-const operator*().

Then again, if iter were some form of smart pointer, one might want to
write

*(i++) = x;

because it's valid for normal pointers. Make sense, or am I lacking
caffeine?

Maybe, I am missing something, but isn't that confusing:

T const * <--> const_iterator

and:

T * const <--> iterator const


The following compiles:


class iter_dummy {

int* ptr;

public:

iter_dummy ( int i )
: ptr ( new int ( i ) )
{}

~iter_dummy ( void ) {
delete ptr;
}


iter_dummy const & operator++ ( int ) {
return ( *this );
}

int & operator* ( void ) const {
return ( *ptr );
}

}; // iter_dummy


int main ( void ) {
iter_dummy iter ( 4 );
*(iter++) = 5;
}


Note how operator*() is const as it does not change the iterator but only
the pointee. Thus, you can have iter++ return a const reference, yet
*(iter++) be and lvalue.

Also, note that the standard, e.g., in the description of
std::reverse_iterator, sets a corresponding precedence: the signature of
the dereferencing operator is:

reference operator*() const;



Best

Kai-Uwe Bux
 
B

benben

Totally up to you. While the behaviour of pre- and post-increment
is somewhat expected, based on the behaviour of the built-in types,
'other functions' are certaintly not. And even then, if you are
the one who designs and implements pre- and post-increments for
your UDTs, you're free to make them do what you please. For all
we care, they can all return 'void'. Do as your model dictates.
There is no good enough general rule.


However, if you want your overloaded operators to behave just like those
of built-in types then you should consider making the return type non-const.

Operators like ++ typically returns a self-reference and are themselves
hardly a const operation. In order to use the operator the user must
have a non-const reference to the object so it is reasonable to assume
the user already being in power of legally modifying the object, which
makes returning a const reference from the operator less convincing.

Regards,
Ben
 
I

Ian Collins

Kai-Uwe Bux said:
int & operator* ( void ) const {
return ( *ptr );
}

}; // iter_dummy


int main ( void ) {
iter_dummy iter ( 4 );
*(iter++) = 5;
}


Note how operator*() is const as it does not change the iterator but only
the pointee. Thus, you can have iter++ return a const reference, yet
*(iter++) be and lvalue.
Good point, I was a little short on caffeine.
 

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,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top