Consider the paradigmatic max
template function, std::max()
:
// From the STL
// TEMPLATE FUNCTION _Debug_lt
template
(answer removed) See Herb Sutters GOTW article on binding const references to temporaries.
Edit: I removed the answer since it was actually wrong (thanks for making that clear to me), so all I leave is the link to a somewhat related article. But beware: The feature described in the article does not apply here!
Yes, it's a dangling reference.
Yes, it's a gotcha.
A version that returns by value might be useful provided that you use it by default, and switch to by-reference in the cases where you need it. If you use the by-reference one by default and only switch to the by-value when you need it then you'll still fall foul of the gotcha, because realizing that you need it is the same thing as realizing you should have written const A a_= ::max(A(), A());
.
Unfortunately the by-value one introduces a new gotcha:
A a, b, c;
mymax(a, b) = c; // assigns to temporary, not to a or b
(Actually, looking at this code I reckon if you call it max_by_val
then you won't write this).
You could return by const value, and some people used to recommend that operator overloads should return by const value. But that introduces a performance gotcha in C++11:
A a, b, c;
c = constmymax(a, b); // copies from const rvalue instead of moving.
and even in C++03 it prevents the equivalent explicit optimization swap(c, constmymax(a,b))
.