Overloading Function Templates for C-strings

The following snippet code is an example from book c++ templates. My question is why the the statement return max (max(a,b), c) in the last line becomes a runtime error. Could anyone give me some hints? Thanks!

#include <cstring>
// maximum of two values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b)
{
return b < a ? a : b;
}
// maximum of two C-strings (call-by-value)
char const* max (char const* a, char const* b)
{
return std::strcmp(b,a) < 0 ? a : b;
}
// maximum of three values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c); // error if max(a,b) uses call-by-value
}
int main ()
{
auto m1 = ::max(7, 42, 68); // OK
char const* s1 = "frederic";
char const* s2 = "anica";
char const* s3 = "lucas";
auto m2 = ::max(s1, s2, s3); // run-time ERROR
}

Answer

char const* max (char const* a, char const* b) returns an const char * variable by value. Then T const& max (T const& a, T const& b, T const& c) creates a temporary variable that stores that value and returns a const& reference to it (with T = const char *). That temporary pointer does not exist, when auto m2 = is assigned. Most probably, you print or inspect the value later, which causes some kind of “runtime error”.

I guess, return a reference to const char * from the start.

char const * const& max (char const * const& a, char const * const& b) {
   return std::strcmp(b, a) < 0 ? a : b;
}