std::signbit
В прошлом посте мы уже упоминали std::signbit. Сегодня мы посмотрим на эту сущность по-подробнее.
По сути, это самый говорящий и плюсовый чтоли способ узнать знаковый бит числа, который появился в нашем арсенале с приходом С++11. Причем не только целого, но и числа с плавающей точкой. Хотя на самом деле даже наоборот.
вот такие перегрузки мы имеем для floating-point чисел. А вот такую:
для целых. Последняя перегрузка является дополнительной. Это значит, что в имплементации стандартной библиотеки она не обязана выглядеть прям в точности так. Единственное требование - перегрузки должны быть достаточными, чтобы определить попадание интегрального типа в функцию.
В чем особенность целочисленной перегрузки. В том, что число, которое туда попадает трактуется, как double. Поэтому выражение std::signbit(num) эквивалентно std::signbit(static_cast<double>(num)).
Также эта функция детектирует наличие знакового бита у нулей, бесконечностей и NaN'ов. Да, да. У нуля есть знак. Так что 0.0 и -0.0 - не одно и то же. И если вы внимательные, то заметили даже у NaN есть знак. И std::signbit - один из двух возможных кроссфплатформенных способов узнать знак NaN. Этот факт еще больше мотивирует использовать эту функцию(в ситуациях, где это свойство решает).
Начиная с 23 стандарта функция становится constexpr, что не может не радовать любителей compile-time вычислений.
Для языка С тоже кстати есть похожая сущность. Только там это макрос
И для него гарантируется такое поведение: для положительных чисел возвращаем ноль, а для отрицательных - ненулевое целое число.
Мне кажется, что в повседневной разработке(там где не нужно выжимать все возможные такты и кода) плюсовое решение будет более предпочтительным, по сравнению с аналогами. Говорящее название и поддержка стандрата - наши главные друзья.
Look for signs in life. Stay cool.
#cpp23 #cpp11 #goodoldc
В прошлом посте мы уже упоминали std::signbit. Сегодня мы посмотрим на эту сущность по-подробнее.
По сути, это самый говорящий и плюсовый чтоли способ узнать знаковый бит числа, который появился в нашем арсенале с приходом С++11. Причем не только целого, но и числа с плавающей точкой. Хотя на самом деле даже наоборот.
bool signbit( float num );
bool signbit( double num );
bool signbit( long double num );
вот такие перегрузки мы имеем для floating-point чисел. А вот такую:
template< class Integer >
bool signbit( Integer num );
для целых. Последняя перегрузка является дополнительной. Это значит, что в имплементации стандартной библиотеки она не обязана выглядеть прям в точности так. Единственное требование - перегрузки должны быть достаточными, чтобы определить попадание интегрального типа в функцию.
В чем особенность целочисленной перегрузки. В том, что число, которое туда попадает трактуется, как double. Поэтому выражение std::signbit(num) эквивалентно std::signbit(static_cast<double>(num)).
Также эта функция детектирует наличие знакового бита у нулей, бесконечностей и NaN'ов. Да, да. У нуля есть знак. Так что 0.0 и -0.0 - не одно и то же. И если вы внимательные, то заметили даже у NaN есть знак. И std::signbit - один из двух возможных кроссфплатформенных способов узнать знак NaN. Этот факт еще больше мотивирует использовать эту функцию(в ситуациях, где это свойство решает).
Начиная с 23 стандарта функция становится constexpr, что не может не радовать любителей compile-time вычислений.
Для языка С тоже кстати есть похожая сущность. Только там это макрос
#define signbit( arg ) /* implementation defined */
И для него гарантируется такое поведение: для положительных чисел возвращаем ноль, а для отрицательных - ненулевое целое число.
Мне кажется, что в повседневной разработке(там где не нужно выжимать все возможные такты и кода) плюсовое решение будет более предпочтительным, по сравнению с аналогами. Говорящее название и поддержка стандрата - наши главные друзья.
Look for signs in life. Stay cool.
#cpp23 #cpp11 #goodoldc
Обновления в отношениях static_assert и if constexpr
Наш подписчик Вадим упомянул о важном изменении в отношениях static_assert и if constexpr. Эти изменения вступили в силу с приходом С++23 и говорят о том, что теперь программа не считается ill-formed, даже если static_assert фейлится для всех специализаций.
Посмотрим на уже заезженном примере:
Создали структуру пустышку и использовали функцию to_str по всем трем веткам условия. И если закомментировать последний вывод в консоль - все корректно компилируется и выполняется. Но как только мы инстанцируем специализацию с пессимистичной веткой условия, компиляция падает на ассерте.
Не у многих есть возможность попробовать 23-е плюсы на своих машинках, поэтому оставлю ссылку на годболт, чтобы вы могли поиграться с примером.
До прихода 23-х плюсов была очевидная проблема с этим static_assert'ом. Вроде бы это очень логично писать условия как в примере выше и ожидать, что это сработает. Да и наличие смешного донельзя воркэраунда с шаблонным типозависимым выражением, которое все равно возвращает false, как бы намекает, что что-то не так. Радостно видеть развитие языка и закрытие таких болючих пробелов.
Fix your flaws. Stay cool.
#cpp23 #template
Наш подписчик Вадим упомянул о важном изменении в отношениях static_assert и if constexpr. Эти изменения вступили в силу с приходом С++23 и говорят о том, что теперь программа не считается ill-formed, даже если static_assert фейлится для всех специализаций.
Посмотрим на уже заезженном примере:
template <typename T>
std::string to_str(T t) {
if constexpr (std::is_constructible_v<std::string, T>)
return t;
else if constexpr (std::is_arithmetic_v<T>)
return std::to_string(t);
else
static_assert(false, "cannot convert type to std::string");
}
class A{};
int main()
{
std::cout << to_str("qwe") << std::endl; // OK
std::cout << to_str(5.0) << std::endl; // OK
std::cout << to_str(A{}) << std::endl; // static_assert failed
}
Создали структуру пустышку и использовали функцию to_str по всем трем веткам условия. И если закомментировать последний вывод в консоль - все корректно компилируется и выполняется. Но как только мы инстанцируем специализацию с пессимистичной веткой условия, компиляция падает на ассерте.
Не у многих есть возможность попробовать 23-е плюсы на своих машинках, поэтому оставлю ссылку на годболт, чтобы вы могли поиграться с примером.
До прихода 23-х плюсов была очевидная проблема с этим static_assert'ом. Вроде бы это очень логично писать условия как в примере выше и ожидать, что это сработает. Да и наличие смешного донельзя воркэраунда с шаблонным типозависимым выражением, которое все равно возвращает false, как бы намекает, что что-то не так. Радостно видеть развитие языка и закрытие таких болючих пробелов.
Fix your flaws. Stay cool.
#cpp23 #template