By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,903 Members | 1,670 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,903 IT Pros & Developers. It's quick & easy.

why reture "const &"?

P: n/a
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!!

Jul 22 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
ze*******@gmail.com wrote:

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
Jul 22 '05 #2

P: n/a
"Jonathan Mcdougall" <jo***************@DELyahoo.ca> wrote in message
news:Kc********************@weber.videotron.net...
ze*******@gmail.com wrote:
>
> 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;


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

DW

Jul 22 '05 #3

P: n/a
zealotcat at gmail.com wrote:
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++Re...umns/jan95.pdf
Kind regards,

Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Jul 22 '05 #4

P: n/a
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
Jul 22 '05 #5

P: n/a

"David White" <no@email.provided> wrote in message
news:1_*****************@nasal.pacific.net.au...
To prevent atrocities like

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


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.
Jul 22 '05 #6

P: n/a
jeffc wrote:
"David White" <no@email.provided> wrote in message
news:1_*****************@nasal.pacific.net.au...
To prevent atrocities like

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


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.


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

Jul 22 '05 #7

P: n/a
Niels Dekker - no reply address wrote:
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?


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
Jul 22 '05 #8

P: n/a
simont wrote:
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.

Jul 22 '05 #9

P: n/a
"simont" <s_********@yahoo.co.uk> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
David White wrote:
"Jonathan Mcdougall" <jo***************@DELyahoo.ca> wrote in message
std::max(a, b) = 2;


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?


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

Jul 22 '05 #10

P: n/a

simont wrote:
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 ;)
--
Vladimir

Jul 22 '05 #11

P: n/a
ze*******@gmail.com wrote:
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
Jul 22 '05 #12

P: n/a
ze*******@gmail.com wrote:
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.

--

Cheers
--
Hewson::Mike
"This letter is longer than usual because I lack the time to make it
shorter" - Blaise Pascal
Jul 22 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.