I’ve started reading C++ Templates – the complete guide by Josuttis and Vandevoorde.
And my tiny mind is stuck.
The authors state that “You should limit your changes to the number of parameters or to specifying template parameters explicitly”, using this as an example that causes problems:
template <typename T>
inline T const& max (T const& a, T const& b)
{
return a < b ? b : a;
}
// maximum of two C-strings
inline char const* const& max( char const* a, char const* b)
{
return std::strcmp(a, b) < 0 ? b : a;
}
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return max( max(a,b), c);
}
They say that using the 3 argument version of max is an error –
const char * s1 = "fred";
const char * s2 = "anica";
const char * s3 = "lucas";
::max(s1, s2, s3); // ERROR
“because for C-strings, max(a,b) creates a new, temporary local value that may be returned by the function by reference.”. But I compiled and ran it just fine.
Can anyone explain what the author is saying in this example?
The problem is that the overload for “maximum of two C-strings” takes its two arguments by value, but then returns a reference to one of them. Returning a reference to a local variable is A Bad Idea (once the local variable is destroyed when the function returns, the reference cannot be used, so it’s useless).
You can fix it by taking both of the
const char*s by const reference:The original version probably does compile, but if you use the value returned from the call to
max(which you do, since you use the result ofmax(a,b)when you callmax(max(a,b),c)), the behavior is undefined (because you’re using an object that has been destroyed).