Search code examples
c++templatespass-by-referencepass-by-value

Question from C++ Templates: The Complete guide 2nd


#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
}

The problem is that if you call max() for three C-strings, the statement return max (max(a,b), c); becomes a run-time error because for C-strings, max(a,b) creates a new, temporary local value that is returned by reference, but that temporary value expires as soon as the return statement is complete, leaving main() with a dangling reference.

max(a, b) call nontemplate ::max(char const* a, char const* b), why it will create a new, temporary local value.

I tested this code on VS2022, no errors.


Solution

  • This function

    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
    }
    

    returns a reference to a temporary pointer of the type const char * returned by the expression

    max (max(a,b), c)
    

    used in the return statement of the function because this function

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

    returns a copy of the value of one of the pointers passed to it by value.

    So the reference will be invalid because the temporary object will not be alive after exiting the function.