#c #overloading #c-strings #function-templates
Вопрос:
Следующий фрагмент кода является примером из шаблонов book c . Мой вопрос заключается в том,почему оператор, возвращающий max (max(a, b), c) в последней строке, становится ошибкой во время выполнения. Кто-нибудь может дать мне несколько советов? Спасибо!
#include <cstring>
// maximum of two values of any type (call-by-reference)
template<typename T>
T constamp; max (T constamp; a, T constamp; 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 constamp; max (T constamp; a, T constamp; b, T constamp; 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
}
Комментарии:
1.
warning: returning reference to local temporary object return max (max(...)
2. не могли бы вы более подробно объяснить,почему max(a, b) создает новое временное локальное значение, которое возвращается по ссылке? Поскольку char const* max (char const* a, char const* b) применяется к max(a,b), где передаются указатели, как будет создано временное локальное значение?
3.
T constamp; max
возвращает временную постоянную ссылку на a .const char *
Указатели также являются переменными. Пожалуйста, сделайте отступ в своем коде.4. Вы можете указать первый тип параметра с переменной, чтобы избежать этого gcc.godbolt.org/z/6EEesMnW9
Ответ №1:
char const* max (char const* a, char const* b)
возвращает const char *
переменную по значению. Затем T constamp; max (T constamp; a, T constamp; b, T constamp; c)
создает временную переменную, в которой хранится это значение, и возвращает constamp;
ссылку на нее (с T = const char *
). Этот временный указатель не существует, когда auto m2 =
он назначен. Скорее всего, вы распечатаете или проверите значение позже, что вызовет какую-то «ошибку во время выполнения».
Я думаю, верните ссылку на const char *
с самого начала.
char const * constamp; max (char const * constamp; a, char const * constamp; b) {
return std::strcmp(b, a) < 0 ? a : b;
}