Я хочу вернуть текущее значение логической переменной/члена данных и установить для него значение 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++.
Этот вопрос не является дубликатом: Самый эффективный способ вернуть + сбросить переменную-член? Речь идет о векторе.
У вас есть функция, которая делает то, что вы от нее хотите. Что в этом плохого? Позвольте компилятору сделать свое дело
Обратите внимание, что ваш код не транслируется в инструкции процессора напрямую, компилятор творит чудеса и, возможно, сохраняет данные в регистрах или полностью исключает переменные, просто пишите работающий код и не заботьтесь о синтаксической оптимизации.
Моя проблема в том, что требуется 3 строки кода и одна дополнительная переменная, в то время как для этого нужно всего лишь 1 или несколько строк кода и никаких дополнительных переменных. Дело не в производительности.
Вы все равно можете написать свою служебную функцию (если std ее еще не предоставляет) для выполнения этой работы, тогда благодаря служебной функции у вас будет однострочный код. (и даже лучше, чем нечитаемый трюк).
@elechris Но ваш код читаем, не требует пояснений и, следовательно, удобен в обслуживании. Остроты не обязательно являются целью разработки программного обеспечения. Единственное улучшение — использовать более обобщенную функцию, как указано в ответе. Так что примите это :)
std::exchange() — это то, что вам нужно, оно присваивает новое значение что-то, возвращая свое старое значение.
bool getAndClearX()
{
return std::exchange(x, false);
}
Именно то, о чем просил ОП, но «под капотом» exchange
делает именно то, что делает оригинал getAndClearX
. Так что все еще «тратите» копию (old_value
) значения. :-)
@BoP дело не в производительности. А вот насчет меньшего количества строк кода. Кажется, нет необходимости добавлять дополнительную переменную и две строки кода для простого получения старого значения и его очистки. Этот ответ идеален. Я не хочу писать шаблон или функцию для чего-то такого простого. Если он есть в стандартной библиотеке, то он является частью языка, и поэтому я не считаю, что он требует дополнительного кода. Мое приложение представляет собой графический интерфейс, и я хочу получать флаги, указывающие, что кнопки были нажаты. На мой взгляд, получение и очистка флага в одной строке проще. Я понимаю, что не у всех есть такие предпочтения.
«Я хочу вернуть текущее значение логической переменной/члена данных и установить для него значение false в одном операторе…» Почему? Микрооптимизация?