Daily bit(e) C++. constexpr if из C++17
Добавлено 22 октября 2026 в 23:05
Daily bit(e) C++ 151, конструкция if, вычисляемая на этапе компиляции, – constexpr if (появилась в C++17).

Конструкция constexpr if из C++17 позволяет отказаться от использования макросов в большинстве ситуаций, где они раньше были необходимы.
Она также упрощает написание обобщенных функций и метапрограммирование, а в сочетании с концептами из C++20 позволяет адаптировать код в зависимости от того, какими свойствами обладают типы аргументов функции.
#include <ranges>
constexpr inline bool feature_x24_enabled = true;
// Замена макросов
void some_function()
{
if constexpr (feature_x24_enabled)
{
// что-то особенное для функции x24
}
}
// Функция, возвращающая разные типы в зависимости от типа аргумента
auto generic_function(auto x)
{
if constexpr (std::is_integral_v<decltype(x)>)
{
// аргумент целочисленного типа -> возвращает std::string
return std::to_string(x);
}
else if constexpr (std::is_floating_point_v<decltype(x)>)
{
// аргумент типа с плавающей запятой -> возвращает int64_t
return static_cast<int64_t>(x);
}
else
{
// в противном случае возвращает void
return;
}
}
// Работает с концептами из C++20:
void custom_algorithm(auto&& rng)
{
using type = decltype(rng);
if constexpr (std::ranges::random_access_range<type>)
{
// реализация для random_access_range
}
else if constexpr (std::ranges::bidirectional_range<type>)
{
// реализация для bidirectional_range
}
else
{
// резервная реализация
}
}
int main()
{
auto r1 = generic_function(10);
// decltype(r1) == std::string
static_assert(std::is_same_v<decltype(r1),std::string>);
auto r2 = generic_function(2.4);
// decltype(r2) == int64_t
static_assert(std::is_same_v<decltype(r2),int64_t>);
}
