Я работаю над большой кодовой базой. При рефакторинге кода я обнаружил странное поведение, связанное со ссылкой. Ниже приведен минимальный код для объяснения моего вопроса.
#include <iostream>
int main() {
// case 1
{
int start = 1;
const int &eRef = start > 0 ? start : 9;
start = 2;
std::cout << start << eRef;
}
std::cout << std::endl;
// case 2
{
int start = 1;
int end = 9;
const int &eRef = start > 0 ? start : end;
start = 2;
std::cout << start << eRef;
}
std::cout << std::endl;
return 0;
}
Вывод приведенного выше кода
21
22
Ожидаю выхода 22
для обоих случаев. Но получаются разные результаты для обоих случаев.
Это может быть стандартным, но я хотел бы знать причину этого.
Самое смешное, что когда вы извлекаете > 0 ? start : 9;
, он ведет себя так, как ожидалось. Может, тут что-то с привязкой ссылки к литералу?
@Mat Вы правы, это дубликат. Краткое описание OP: start > 0 ? start : 9
дает вам rvalue (и, следовательно, создается временный объект), start > 0 ? start : end
дает вам lvalue. Также интересно подумать о том, что происходит с start > 0 ? start : (const int &) 9
.
Решение: не используйте магические числа. Вместо > 0 ? start : 9;
вы должны были ввести const int
со значением 9
, а затем приступить к вычислению тернарного оператора. Если да: int start = 1;const int literal9 = 9; const int &eRef = start > 0 ? start : literal9;
, все работает как положено
@Fureeish Ты серьезно? Вы рекомендуете константу под названием literal9
??
@Pi Это "буквально" глупо;)
@LightnessRacesInOrbit хорошо, вы или OP рекомендуете написать что-то похожее на код в исходном вопросе в реальном коде? Очевидно нет. Я назвал его literal9
, потому что мне пришлось придумать имя некоторые. Имя должно указывать на использование этой переменной. Tbh, если нет оправдания для использования любого другого имени, следует подумать, не ошибочна ли логика
@Fureeish Нет, и где я сказал, что рекомендую это? Ваше предложение заменить магическое число константой является правильным, но literal9
- худший способ сделать это (хуже, чем исходный подход). Название должно описывать то, что есть 9, а не саму цифру 9. В вашем комментарии этого не сказано.
И я не сказал, что рекомендую такие имена. Это ни ответ, ни инструкция. Это код, который иллюстрирует идею с потенциальным исправлением, и если вы действительно хотите тратить свое время на споры об имени переменной в комментарии, вы можете это сделать. Если уж больно глазам, представьте, есть более удобное название:>