Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.53/19: Рейтинг темы: голосов - 19, средняя оценка - 4.53
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47

Почему этот код не выполнится должным образом?

21.10.2022, 12:13. Показов 4197. Ответов 51

Студворк — интернет-сервис помощи студентам
На одном форуме наткнулся на то, что одному парню на собеседовании задали написать функцию нахождения минимума, он написал следующим образом:

C++
1
2
3
4
5
template <class T> 
T& min (T& a, T& b) 
{
  return (a<b)?a:b;
}
собеседующий ответил, что такой код не отработает должным образом на вызове:
min(a, b+1)

у меня вопрос, почему не работает? я запустил и он работает. (параметры стоило бы сделать константными, да, но почему код не отработает должным образом?)
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.10.2022, 12:13
Ответы с готовыми решениями:

Почему не работает должным образом?
vremyagoda = input (&quot;Введите какое сейчас время года? Зима?, Осень? Лето?, а может быть Весна?: &quot;) vremyasutok = input (&quot;Что у...

Не понимаю почему программа не работает должным образом
все работает исправно кроме условного оператора if,когда переменные меняются местами ничего не происходить код: a = float(input()) ...

Почему текст в колонках DataTables не форматируется должным образом?
При инициации таблицы задал классы колонок {className:&quot;Price&quot;,&quot;width&quot;: &quot;70px&quot; ,targets:, render:$.fn.dataTable.render.number( ' ',...

51
 Аватар для Tanya2007
593 / 230 / 72
Регистрация: 13.05.2020
Сообщений: 412
21.10.2022, 12:59
Цитата Сообщение от NewFive Посмотреть сообщение
min(a, b+1)
b+1 - при такой передаче это временный объект, который создается для передачи в функцию, в отличие от уже инициализированной переменной b. Передать в функцию временный объект по ссылке нельзя, поэтому либо делать так:
C++
1
2
3
4
5
6
7
8
9
template <class T>
T& min (T& a, T& b)
{
return (a<b)?a:b;
}
 
 
b = b+1;
    std::cout << min(a, b) << "\n";
либо шаблон писать без ссылок:
C++
1
2
3
4
5
6
7
template <class T>
T min (T a, T b)
{
return (a<b)?a:b;
}
 
std::cout << min(a, b + 1) << "\n";
Тогда он будет принимать аргументы по значению, т.е. делать копии переменных при вызове функции min

Добавлено через 6 минут
Цитата Сообщение от NewFive Посмотреть сообщение
я запустил и он работает
а у меня компилятор ругается:
[Error] invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'
0
101 / 95 / 10
Регистрация: 31.08.2022
Сообщений: 1,014
21.10.2022, 13:07
может быть передавать итог
min(a, (b+1))
хотя... я бы за такое руки оторвал
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2022, 13:32
Цитата Сообщение от Tanya2007 Посмотреть сообщение
либо шаблон писать без ссылок:

C++
1
2
3
4
5
template <class T>
const T& min(const T& a, const T& b)
{
    return (a < b) ? a : b;
}
Добавлено через 4 минуты
Цитата Сообщение от SergP01 Посмотреть сообщение
может быть передавать итог
min(a, (b+1))
А какая разница?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,220
21.10.2022, 13:35
Цитата Сообщение от NewFive Посмотреть сообщение
но почему код не отработает должным образом?)
Странный вопрос. Потому что он даже не скомпилируется.
1
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
21.10.2022, 13:40
А лучше сразу обе две. Константную и не константную.

Цитата Сообщение от NewFive Посмотреть сообщение
я запустил и он работает.
А как оно заработало, если оно не скомпилируется даже?! Оо
0
 Аватар для Nishen
1358 / 856 / 366
Регистрация: 26.02.2015
Сообщений: 3,814
21.10.2022, 13:49
Цитата Сообщение от Tanya2007 Посмотреть сообщение
b+1 - при такой передаче это временный объект
По константной ссылке можно, срок жизни объекта увеличивается при этом до времени жизни ссылки.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.10.2022, 13:53
Цитата Сообщение от NewFive Посмотреть сообщение
почему не работает?
потому что выражаение b + 1 порождает временный объект.
а временные объекты нельзя биндить на мутабельные ссылки T&
"мутабельные ссылки" - это ссылки, через которые можно изменить объект.

т.е., нельзя писать код вида:
C++
1
2
// error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
int& ref = 1;
в примере выше,
ошибка происходит из-за попытки инициализировать мутабельную ссылку int&
временным объектом 1


поскольку в твоем случае функцию min, можно вызвать с временным объектом,
то возвращать результат по ссылке, это - плохая идея:
C++
1
2
const int v = 10;
const int& r = min(v, v - 1);
в пример выше, время жизни временного объекта v-1 завершится сразу же,
как только завершится работа функции min
поэтому, ссылка const int& r будет ссылаться на мертвый объект.

таким образом, это - плохой дизайн, который провоцирует ошибки.



если очень нужна возможность возвращать по ссылкам,
там, где это возможно, тогда нужно что-то вроде этакого:

https://rextester.com/MUOAX16926

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <type_traits>
 
#define dIS_RVALUE(t) \
  ::std::is_rvalue_reference<t>::value
 
#define dENABLE(...) \
    ::std::enable_if_t<__VA_ARGS__, void>
 
#define dFOR_RVALUE \
    class = dENABLE( dIS_RVALUE(T1&&) || dIS_RVALUE(T2&&) )
 
#define dFOR_LVALUE \
    class = dENABLE( !dIS_RVALUE(T1&&) && !dIS_RVALUE(T2&&) )
    
 
template<class T1, class T2, dFOR_RVALUE>
constexpr auto min (T1&& a, T2&& b) noexcept
    { return (a < b) ? a : b; }
 
template<class T1, class T2, dFOR_LVALUE>
constexpr decltype(auto) min (T1&& a, T2&& b) noexcept
    { return (a < b) ? a : b; }
 
int main()
{
    int a = 10, b = 10;
    
    // функция возвращвает по ссылке (int&)
    std::cout << "1) " << min(a, b) << '\n';
 
    // функция возвращвает по значению (int)
    std::cout << "2) " << min(a, b - 1) << '\n';
    
    using x = decltype(min(a, b));
    using z = decltype(min(a, b - 1));    
    static_assert(::std::is_same_v<x, int&>);
    static_assert(::std::is_same_v<z, int>);    
}
2
101 / 95 / 10
Регистрация: 31.08.2022
Сообщений: 1,014
21.10.2022, 17:13
Цитата Сообщение от Folian Посмотреть сообщение
А какая разница
я не пробывал..... но подозреваю, что для начала это скомпилится.... ибо итоговый результат в стек пойдёт...
0
694 / 304 / 99
Регистрация: 04.07.2014
Сообщений: 851
21.10.2022, 17:44
Цитата Сообщение от NewFive Посмотреть сообщение
у меня вопрос, почему не работает? я запустил и он работает.
Сделаю предположение, что у тебя было в коде
C++
1
using namespace std;
1
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2022, 17:46
Цитата Сообщение от SergP01 Посмотреть сообщение
но подозреваю, что для начала это скомпилится
Нет.
Аргумент в любом случае вычисляется перед функцией и передаётся результат, что со скобками, что без; получится rvalue, на который нельзя кинуть обычную сцылку.

Добавлено через 43 секунды
Цитата Сообщение от AlexVRud Посмотреть сообщение
Сделаю предположение, что у тебя было в коде
Точняк, похоже
0
694 / 304 / 99
Регистрация: 04.07.2014
Сообщений: 851
21.10.2022, 17:48
В догонку, для проверки: https://onlinegdb.com/BoEnHMCIJ
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2022, 17:52
Можно даж чёнить вывести для наглядности.
C++
1
2
3
4
5
6
template <class T> 
T& min (T& a, T& b) 
{
    std::cout << "Invisible text";
    return (a<b)?a:b;
}
0
101 / 95 / 10
Регистрация: 31.08.2022
Сообщений: 1,014
21.10.2022, 18:19
Цитата Сообщение от Folian Посмотреть сообщение
Нет.
Аргумент в любом случае вычисляется перед функцией и передаётся результат,
есть у меня подозрение, что туда ... тупо- не правильный адрес передаётся..
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2022, 18:32
Цитата Сообщение от SergP01 Посмотреть сообщение
адрес передаётся
Адрес? Какой адрес? Откуда адрес?
0
694 / 304 / 99
Регистрация: 04.07.2014
Сообщений: 851
21.10.2022, 18:35
Лучший ответ Сообщение было отмечено NewFive как решение

Решение

NewFive, попробую объяснить.

Два варианта возможного кода, когда скомпилируется и когда нет

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Компилируется, но есть большое НО
#include <iostream>
 
using namespace std;
 
template <class T> 
T& min (T& a, T& b) 
{
    std::cout << "Find min ...\n";
    return (a<b)?a:b;
}
 
int main()
{
    int a = 10;
    int b = 3;
    cout << min(a, b + 1);
 
    return 0;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Не компилируется
#include <iostream>
 
template <class T> 
T& min (T& a, T& b) 
{
    std::cout << "Find min ...\n";
    return (a<b)?a:b;
}
 
int main()
{
    int a = 10;
    int b = 3;
    std::cout << min(a, b + 1);
 
    return 0;
}
Почему не работает второй вариант:

Ссылка вида T& b предполагает, что объект должен быть готовым к изменениям. Мы же не можем написать
C++
1
(b + 1) = a;
Такие объекты помечаются как lvalue, т.е. те которые могут быть слева
А вот (b+1) - помечаются как rvalue, т.е. те которые должны быть справа

Так что ещё один компилирующейся и работающий пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Компилируется и работает, но для min(a, b)
#include <iostream>
 
template <class T> 
T& min (T& a, T& b) 
{
    std::cout << "Find min ...\n";
    return (a<b)?a:b;
}
 
int main()
{
    int a = 10;
    int b = 3;
    std::cout << min(a, b);
 
    return 0;
}
В котором оба параметра min являются lvalue и ссылки на них можно взять.

Почему компилируется первый вариант

Есть такой стандартный шаблон:

C++
1
2
template< class T >
const T& std::min( const T& a, const T& b );
Написав:
C++
1
using namespace std;
можно смело его использовать по короткому имени min.

Компилятор видит два определения: min(const T& a, const T& b) и min(T& a, T& b), выбирает первый как более подходящий.
НО вызывается не нами написанный min, а std::min

Ну и последний пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
using namespace std;
 
template <class T> 
T& min (T& a, T& b) 
{
    std::cout << "Find min ...\n";
    return (a<b)?a:b;
}
 
int main()
{
    int a = 10;
    int b = 3;
    cout<< min(a, b);
 
    return 0;
}
Компилятор видит два определения: min(const T& a, const T& b) и min(T& a, T& b), выбирает второй как более подходящий.
2
101 / 95 / 10
Регистрация: 31.08.2022
Сообщений: 1,014
21.10.2022, 18:47
Цитата Сообщение от Folian Посмотреть сообщение
дрес? Какой адрес? Откуда адрес
там вроде &b
ежели ему плюс один сделать....
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,220
21.10.2022, 18:50
Цитата Сообщение от SergP01 Посмотреть сообщение
там вроде &b
ежели ему плюс один сделать....
Где "там"?
0
694 / 304 / 99
Регистрация: 04.07.2014
Сообщений: 851
21.10.2022, 18:59
Цитата Сообщение от SergP01 Посмотреть сообщение
ежели ему плюс один сделать....
Там функция просит изменяемую ссылку на аргумент, т.е. изменяемую ссылку от b+1, а b+1 - это временный объект и помечен как rvalue. А rvalue-объекты изменять нельзя (но на них можно брать константную ссылку). Пояснения смотри выше.

А адреса там нет. Там есть
C++
1
min(T &a, T &b)
, т.е. функция от двух изменяемых ссылок. Это описание типа параметров. И нигде далее не используются адреса в явном виде. Ни когда вызывается функция, ни в её коде.
0
101 / 95 / 10
Регистрация: 31.08.2022
Сообщений: 1,014
21.10.2022, 19:10
Цитата Сообщение от AlexVRud Посмотреть сообщение
т.е. функция от двух изменяемых ссылок
мы сейчас в терминологиях запутаемся или подерёмся....
для меня ... &b - это адрес где эта переменна лежит
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.10.2022, 19:10
Помогаю со студенческими работами здесь

Код выводится в браузер, а не обрабатывается должным образом.
Здравствуйте!Проблема такая: при загрузке этого кода браузер выводит этот код, а должен график синуса Что может быть не так?? &lt;?php ...

Не получается должным образом получить HTML код сайта программным способом
Здравствуйте! Недавно решил сделать прогу на C#, а чтобы она нормально работала нужно считывать инф-цию с сайта. Информация считывается, но...

Как изменить код программы чтобы все условия выполнялись должным образом?
Здравствуйте! Вот код программы: #include &lt;iostream&gt; #include &lt;time.h&gt; #include &lt;math.h&gt; using namespace std; int t; ...

Почему невозможно открыть код таким образом и почему форма с ним никак не контактирует
И при двойном клике на элемент, открывается, а точнее переходит, на исходный код. Никак не пойму в чем проблема, а ответ по-любому...

Не работает должным образом LZ-78 (компрессор) c++
Приветствую, форумчане! Прошу помочь с небольшим проектом. Есть код на C++, но не могу реализовать работу с файлами. Только прошу, не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru