0Pricing
C++ Academy · Урок

Условная логика

std::conditional и if constexpr

«Условная логика» — бесплатный урок C++ Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Выбор типов и ветвей

Логика характеристик типов позволяет коду выбирать типы и ветви выполнения во время компиляции. Основные инструменты — std::conditional и if constexpr.

Условный выбор типа

std::conditional_t<cond, A, B> принимает значение A, если cond истинно, и B в противном случае.

#include <iostream>
#include <type_traits>

int main() {
    using T = std::conditional_t<true, int, double>;
    std::cout << std::is_same_v<T, int> << "\n";
    return 0;
}

Выбор типа хранения

Распространённый случай применения: выбирать широкий тип для больших значений, а в остальных случаях — узкий.

#include <iostream>
#include <type_traits>

template <bool Big>
struct Storage {
    using type = std::conditional_t<Big, long long, short>;
};

int main() {
    Storage<true>::type a = 10;
    std::cout << sizeof(a) << "\n";
    return 0;
}

Основы if constexpr

if constexpr (C++17) отбрасывает невыбранную ветвь на этапе компиляции. Для данного типа должна компилироваться только выбранная ветвь.

#include <iostream>
#include <type_traits>

template <typename T>
void describe(T v) {
    if constexpr (std::is_integral_v<T>)
        std::cout << "integer: " << v << "\n";
    else
        std::cout << "other: " << v << "\n";
}

int main() {
    describe(5);
    describe(2.5);
    return 0;
}

Почему if constexpr лучше обычного if во время выполнения

При обычном if обе ветви должны компилироваться для каждого T. При использовании if constexpr отклонённая ветвь не инстанцируется, поэтому она может содержать код, специфичный для типа, который иначе был бы некорректным.

Операции, специфичные для типа

С обычным if это невозможно, поскольку .length() не скомпилировался бы для int.

#include <iostream>
#include <string>
#include <type_traits>

template <typename T>
auto size_of(const T& v) {
    if constexpr (std::is_same_v<T, std::string>)
        return v.length();
    else
        return sizeof(v);
}

int main() {
    std::cout << size_of(std::string("hi")) << "\n";
    std::cout << size_of(42) << "\n";
    return 0;
}

enable_if для перегрузок

До появления if constexpr средство std::enable_if выбирало перегрузки с помощью SFINAE. Если условие ложно, оно исключает функцию из разрешения перегрузки.

#include <iostream>
#include <type_traits>

template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
void only_int(T v) { std::cout << "int " << v << "\n"; }

int main() {
    only_int(7);
    return 0;
}

Объединение условий

Вы можете объединять признаки с помощью &&, || и ! в условиях, проверяемых на этапе компиляции, так же как обычные логические значения.

#include <iostream>
#include <type_traits>

template <typename T>
void check() {
    if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>)
        std::cout << "non-bool integer\n";
    else
        std::cout << "something else\n";
}

int main() {
    check<int>();
    check<bool>();
    return 0;
}

Рекурсивный выбор на этапе компиляции

if constexpr поддерживает рекурсию на этапе компиляции, что удобно для обработки кортежей или наборов параметров по одному элементу.

conjunction и disjunction

В C++17 также появились std::conjunction и std::disjunction для логических операций AND/OR с коротким замыканием над списком признаков.

Выбор подходящего инструмента

Используйте conditional для выбора типа, if constexpr для выбора кода, а enable_if/концепции — для управления разрешением перегрузки. В современном коде для ясности предпочтительны if constexpr и концепции.

Быстрая проверка

Вспомните главное преимущество if constexpr.

Итоги

Вы изучили условную логику на этапе компиляции.

  • conditional_t<c,A,B> выбирает тип
  • if constexpr выбирает код, отбрасывая другую ветвь
  • enable_if управляет разрешением перегрузки с помощью SFINAE
  • Признаки можно объединять логическими операторами

Часто задаваемые вопросы

Урок «Условная логика» бесплатный?

Да — полный текст урока «Условная логика» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Условная логика»?

std::conditional и if constexpr Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Условная логика»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Исследование типов
  2. Преобразование типов
  3. Условная логика
  4. Создание собственных признаков типов
← Назад к C++ Academy