0Pricing
C++ Academy · Урок

std::variant

Типобезопасное объединение

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

Типобезопасное объединение

std::variant хранит ровно одно значение из фиксированного списка типов и запоминает, какое именно. Чтобы использовать его, подключите <variant>.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 10;
    std::cout << std::get<int>(v) << "\n";
}

Присваивание значений разных типов

Вы можете присвоить варианту значение любого из его альтернативных типов. При этом активная альтернатива обновляется автоматически.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 5;
    v = 3.14; // now holds a double
    std::cout << std::get<double>(v) << "\n";
}

Проверка активного типа

std::holds_alternative<T>(v) сообщает, содержит ли вариант в данный момент значение типа T.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 2.0;
    std::cout << std::holds_alternative<double>(v) << "\n";
    std::cout << std::holds_alternative<int>(v) << "\n";
}

Функция index()

v.index() возвращает позицию активного типа в списке типов, начиная с нуля.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double, char> v = (char)65;
    std::cout << v.index() << "\n"; // 2
}

Безопасный доступ с помощью std::get

std::get<T> возвращает значение, если активен тип T, а в противном случае выбрасывает исключение std::bad_variant_access. Никаких незаметно возникающих мусорных значений.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 7;
    try {
        std::cout << std::get<double>(v) << "\n";
    } catch (const std::bad_variant_access& e) {
        std::cout << "wrong type!\n";
    }
}

Не выбрасывающий исключения get_if

std::get_if<T>(&v) возвращает указатель на значение или nullptr, если тип T неактивен. Это удобно для проверок без ветвления.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 9;
    if (auto p = std::get_if<int>(&v))
        std::cout << "int " << *p << "\n";
}

Конструирование по умолчанию

Вариант, сконструированный по умолчанию, содержит значение, инициализированное по правилам значения, для своего первого типа. Располагайте типы так, чтобы первый тип давал разумное значение по умолчанию.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v; // holds int 0
    std::cout << std::get<int>(v) << "\n";
}

Хранение строк

В отличие от обычных объединений, вариант может безопасно хранить нетривиальные типы, такие как std::string; временем их жизни управляет вариант.

#include <iostream>
#include <string>
#include <variant>
int main() {
    std::variant<int, std::string> v = std::string("hello");
    std::cout << std::get<std::string>(v) << "\n";
}

Вариант как возвращаемый тип

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

#include <iostream>
#include <string>
#include <variant>
std::variant<int, std::string> parse(bool ok) {
    if (ok) return 42;
    return std::string("error");
}
int main() {
    auto r = parse(false);
    if (auto s = std::get_if<std::string>(&r)) std::cout << *s << "\n";
}

emplace для изменения на месте

v.emplace<T>(args...) конструирует новое значение типа T непосредственно внутри варианта, переключая активную альтернативу.

#include <iostream>
#include <string>
#include <variant>
int main() {
    std::variant<int, std::string> v = 1;
    v.emplace<std::string>("switched");
    std::cout << std::get<std::string>(v) << "\n";
}

Почему стоит предпочесть std::variant

std::variant сочетает эффективность объединений по использованию памяти с полной типобезопасностью: отслеживает активный тип, управляет временем жизни объектов и запрещает обращения к неправильному типу. На следующем уроке показан самый удобный способ его обрабатывать.

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

Проверьте, насколько хорошо Вы поняли std::variant.

Итоги

Вы узнали о std::variant:

  • Он хранит одно значение из нескольких типов и отслеживает, какое именно.
  • holds_alternative и index() позволяют проверить активный тип.
  • std::get выбрасывает исключение при несовпадении, а get_if возвращает указатель или null.
  • Он безопасно хранит нетривиальные типы, такие как std::string.

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

Урок «std::variant» бесплатный?

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

Чему я научусь в уроке «std::variant»?

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

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

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

Сколько времени занимает урок «std::variant»?

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

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

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

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

  1. Перечисление scoped enum class
  2. Объединения и связанные с ними риски
  3. std::variant
  4. std::visit
← Назад к C++ Academy