why reture "const &"?

Z

zealotcat

template <class T>
inline T const& max (T const& a, T const& b)
{
// if a < b then use b else use a
return a<b?b:a;
}

thanks very much!!
 
J

Jonathan Mcdougall

why reture "const &"?

template <class T>
inline T const& max (T const& a, T const& b)
{
// if a < b then use b else use a
return a<b?b:a;
}

To prevent atrocities like

std::max(a, b) = 2;

and to allow passing and returning of rvalues.


Jonathan
 
N

Niels Dekker - no reply address

zealotcat said:
template <class T>
inline T const& max (T const& a, T const& b)
{
// if a < b then use b else use a
return a<b?b:a;
}

If you return by value (T) instead of by const reference (T const&), you
get a carbon copy of the maximum, not the original. When returning by
(const) reference, the class T doesn't need to have a copy contructor.

BTW, the "const" is necessary because your parameters are const
references as well. You might consider having a non-const version as
well:

template <class T>
inline T& max (T& a, T& b)
{
return a<b?b:a;
}

See also http://www.aristeia.com/Papers/C++ReportColumns/jan95.pdf


Kind regards,

Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
 
S

simont

David said:
Why is that an atrocity? You might want to assign the max of a and b
to 2.

You /can't/ "assign the max of a and b to 2" in any meaningful sense.
Writing
| max(5,7) = 2;
doesn't "assign the max of 5 and 7", because you can't change that.
What would it mean to do so? That I want globally to switch integer
arithmetic to modulo 5?

The function 'max' is usually considered to be returning the larger of
two values, rather than performing side-effects or anything else.
Unless you meant something like

| template <typename T>
| T& larger_of( T& a, T& b ) { return a>b ? a : b; }

where

| int a(5);
| int b(7);
| // change the larger integer for some reason ...
| larger_of(a,b) /= 2;
might make sense. That isn't what max means, though.
 
N

Niels Dekker - no reply address

zealotcat at gmail.com asked:
why return "const &"?

Jonathan Mcdougall replied:
To prevent atrocities like

std::max(a, b) = 2;

What about calling some other non-const member function?

Suppose I'm programming a GUI, and I have an ordered group of buttons on
a window, so that I can say button A < button B. (E.g., based on tab
order.) I might want to do:

void MyFunc(Button & a, Button & b)
{
// Setting the "default property" (or whatever!)
// of the button that has the maximum value.
max(a, b).SetDefault(true);

}

Typically Button::SetDefault is a non-const member function. So I need
a max(a, b) that returns a non-const reference!


Kind regards,

Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
 
J

jeffc

David White said:
Why is that an atrocity? You might want to assign the max of a and b to 2.

Maybe so, but that code won't do it. max is a function that returns a value,
not a variable.
 
J

Jonathan Mcdougall

jeffc said:
Maybe so, but that code won't do it. max is a function that returns a value,
not a variable.

std::max is a function that returns a const
reference, not a value nor a "variable".


Jonathan
 
J

Jonathan Mcdougall

Niels said:
zealotcat at gmail.com asked:



Jonathan Mcdougall replied:



What about calling some other non-const member function?

That is not what std::max was designed to do.
Suppose I'm programming a GUI, and I have an ordered group of buttons on
a window, so that I can say button A < button B. (E.g., based on tab
order.) I might want to do:

void MyFunc(Button & a, Button & b)
{
// Setting the "default property" (or whatever!)
// of the button that has the maximum value.
max(a, b).SetDefault(true);

}

That's quite an ugly function, imho. std::max
will do the correct thing if operator< is
implemented correctly, but getting the maximum or
minimum button makes no sense, whether they are
order by their text of tab stop order. That's a
misuse of std::max.
Typically Button::SetDefault is a non-const member function. So I need
a max(a, b) that returns a non-const reference!

Roll you own.


Jonathan
 
R

Rolf Magnus

simont said:
Writing
| max(5,7) = 2;
doesn't "assign the max of 5 and 7", because you can't change that.

That wouldn't work anyway, neither with a max that returns (and takes)
references (no matter whether they're const or not), nor with one that
returns by value. So that wouldn't be a problem anyway.
What would it mean to do so?

An error.
The function 'max' is usually considered to be returning the larger of
two values, rather than performing side-effects or anything else.

However, even std::max doesn't do this. It returns a const reference, not a
value.
Unless you meant something like

| template <typename T>
| T& larger_of( T& a, T& b ) { return a>b ? a : b; }

where

| int a(5);
| int b(7);
| // change the larger integer for some reason ...
| larger_of(a,b) /= 2;
might make sense. That isn't what max means, though.

max means whatever its programmer makes it mean. I don't see a need to call
it larger_of instead of max.
 
D

David White

simont said:
to 2.

You /can't/ "assign the max of a and b to 2" in any meaningful sense.
Writing
| max(5,7) = 2;
doesn't "assign the max of 5 and 7", because you can't change that.
What would it mean to do so? That I want globally to switch integer
arithmetic to modulo 5?

Of course not. I wasn't referring to constants. I was referring to a and b,
and you could have an l-value version of the template that would work in
that case. I'm not suggesting that such a template should be provided. I'm
just disagreeing that "std::max(a, b) = 2;" is an atrocity. It looks quite
neat and elegant to me, even if hardly anyone would ever need it.

DW
 
V

Vladimir

simont said:
You /can't/ "assign the max of a and b to 2" in any meaningful sense.
Writing
| max(5,7) = 2;
doesn't "assign the max of 5 and 7", because you can't change that.

You can't assign 5 to 2 in any meaningful sense either:

5 = 2;

Does this mean we have to get rid of assignment operator??

Writing max(a, b) = c makes perfect sense either in math or in
programming
At least for those who knows what references are used for ;)
 
D

Dave Rahardja

template <class T>
inline T const& max (T const& a, T const& b)
{
// if a < b then use b else use a
return a<b?b:a;
}

thanks very much!!

Because the input variables are const references. You shouldn't return a
non-const reference to a const object.

By the way, why is everyone on this thread assuming that the original
poster is talking about std::max?

I do like the idea of max returning an lvalue. The expression

max(a, b) = 5;

is succint, clear, and unambiguous.

-dr
 
M

Mike Hewson

template <class T>
inline T const& max (T const& a, T const& b)
{
// if a < b then use b else use a
return a<b?b:a;
}

thanks very much!!
The parameters when the function 'max' is called have type 'T const&' -
meaning 'a' and 'b' are T's ( whatever they are ) that cannot be altered
in this context ( the 'const' ), and reference semantics are used (
possibly to avoid pointer stuff, but there are other reasons ).
For the type 'T' one hopes that the '<' operator is satisfactorily and
sensibly defined with regard to the meaning and usage of type 'T'.
The expression 'a<b' is evaluated in terms of its equivalence to 0, so
the conditional-expression operator as applied ( 'a<b?b:a' ) will
represent 'a' if 'a<b' is non-zero ( 'true' }, and 'b' otherwise.
The function thus returns one of 'a' or 'b' according to that test, but
with the type 'T const&'.
Presumably, this is because if the 'max' function ought not alter 'a'
or 'b' ( the 'const' in the argument list suggests this intention ),
then neither should the function that called 'max' ( to which either 'a'
or 'b' will be returned ).
Assigning to max(a,b) would seem to violate that intent, that is:

max(a,b) = Whatever; // Whatever is of type 'T'.

would be illegal as it stands. Some other function named 'max', but with
a different signature, could be used however - a non-const version for
instance.
 

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

No members online now.

Forum statistics

Threads
474,196
Messages
2,571,036
Members
47,631
Latest member
kukuh

Latest Threads

Top