Можно ли вернуть переменную и обновить ее одним оператором вместо того, чтобы сначала копировать переменную?

Я хочу вернуть текущее значение логической переменной/члена данных и установить для него значение false в одном операторе (или, может быть, в двух).

Что у меня есть сейчас:

bool getAndClearX()
{
    bool copy = x;
    x = false;
    return copy;
}

Следующее не работает из-за короткого замыкания: return x || (x=false);

Следующее не работает из-за UB («неупорядоченная модификация и доступ к x»):

return x + (x=false);
return x ^ (x=false);
return x > (x=false);

Это тоже не работает: return std::max(x,x=false);

Я не знаю, как это сделать, не копируя и не написав свои макросы, шаблоны или функции. Меня устраивает использование стандартной библиотеки C++.

Этот вопрос не является дубликатом: Самый эффективный способ вернуть + сбросить переменную-член? Речь идет о векторе.

«Я хочу вернуть текущее значение логической переменной/члена данных и установить для него значение false в одном операторе…» Почему? Микрооптимизация?

user12002570 20.08.2024 11:20

У вас есть функция, которая делает то, что вы от нее хотите. Что в этом плохого? Позвольте компилятору сделать свое дело

Pepijn Kramer 20.08.2024 11:20

Обратите внимание, что ваш код не транслируется в инструкции процессора напрямую, компилятор творит чудеса и, возможно, сохраняет данные в регистрах или полностью исключает переменные, просто пишите работающий код и не заботьтесь о синтаксической оптимизации.

Ahmed AEK 20.08.2024 11:24

Моя проблема в том, что требуется 3 строки кода и одна дополнительная переменная, в то время как для этого нужно всего лишь 1 или несколько строк кода и никаких дополнительных переменных. Дело не в производительности.

elechris 20.08.2024 13:18

Вы все равно можете написать свою служебную функцию (если std ее еще не предоставляет) для выполнения этой работы, тогда благодаря служебной функции у вас будет однострочный код. (и даже лучше, чем нечитаемый трюк).

Jarod42 20.08.2024 13:26

@elechris Но ваш код читаем, не требует пояснений и, следовательно, удобен в обслуживании. Остроты не обязательно являются целью разработки программного обеспечения. Единственное улучшение — использовать более обобщенную функцию, как указано в ответе. Так что примите это :)

Pepijn Kramer 20.08.2024 13:30
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
6
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

std::exchange() — это то, что вам нужно, оно присваивает новое значение что-то, возвращая свое старое значение.

bool getAndClearX()
{
  return std::exchange(x, false);
}

Именно то, о чем просил ОП, но «под капотом» exchange делает именно то, что делает оригинал getAndClearX. Так что все еще «тратите» копию (old_value) значения. :-)

BoP 20.08.2024 13:39

@BoP дело не в производительности. А вот насчет меньшего количества строк кода. Кажется, нет необходимости добавлять дополнительную переменную и две строки кода для простого получения старого значения и его очистки. Этот ответ идеален. Я не хочу писать шаблон или функцию для чего-то такого простого. Если он есть в стандартной библиотеке, то он является частью языка, и поэтому я не считаю, что он требует дополнительного кода. Мое приложение представляет собой графический интерфейс, и я хочу получать флаги, указывающие, что кнопки были нажаты. На мой взгляд, получение и очистка флага в одной строке проще. Я понимаю, что не у всех есть такие предпочтения.

elechris 20.08.2024 14:40

Другие вопросы по теме