Давайте сделаем это медленно:
::max(s1, s2, s3);
вызывает T const& max (T const& a, T const& b, T const& c)
с T
, являющимся char const*
.
В этом методе мы имеем:
max(a,b)
который вызывает char const* max (char const* a, char const* b)
max(max(a,b), c);
, таким образом, также char const* max (char const* a, char const* b)
И, следовательно, страшная часть (если мы переписываем):
template <typename T>
T const& max (T const& a, T const& b, T const& c)
{
T result = max(max(a,b), c);
return result; // reference to a temporary
}
Потому что T
is char const*
, а max(char const*, char const*)
возвращает копию (указателя), а не постоянную ссылку на указатель.
gcc
помогает диагностировать проблему (см. ideone ):
prog.cpp: In function ‘const T& max(const T&, const T&, const T&) [with T = const char*]’:
prog.cpp:27: instantiated from here
prog.cpp:18: warning: returning reference to temporary
С 18
в качестве return max(....)
в шаблоне и 27
в качестве вызова.
Если вы переписали max
, чтобы "скрыть" это временное значение:
template <typename T> inline T const& max (T const& a, T const& b, T const& c)
{
T const& result = max (max(a,b), c);
return result;
}
Вы помешаете обнаружению gcc (см. ideone ), но это не решит проблему.Clang предупредил бы, что T const& result
связан с временным.
Реальная проблема в том, что char const* max(char const*, char const*)
возвращает значение, поэтому либо все max
должны возвращаться по значениям, либо все max
должны принимать ивернуть константные ссылки ... если вы хотите их перепутать.