CPPPROGLIB Telegram 6104
👁 std::variant — типобезопасный union

std::variant (C++17) — это union, который знает свой текущий тип и гарантирует безопасность.


🐤 Старый подход:

// C-style union — опасно!
union Data {
int i;
double d;
char* str;
};

Data data;
data.i = 42;
std::cout << data.d; // Читаем не то, что записали



🐸 Современный подход:

std::variant<int, double, std::string> data;

data = 42; // Хранит int
data = 3.14; // Теперь хранит double
data = "hello"; // Теперь хранит string

// Безопасное получение значения
if (auto* val = std::get_if<int>(&data)) {
std::cout << "int: " << *val << '\n';
}



🥨 Базовые операции:

std::variant<int, std::string, double> v;

// Установка значения
v = 100;
v = "text";
v.emplace<std::string>("constructed in place");

// Проверка текущего типа
std::cout << v.index(); // Индекс типа: 0, 1, или 2

if (std::holds_alternative<int>(v)) {
std::cout << "Содержит int\n";
}

// Получение значения
try {
auto val = std::get<int>(v); // Бросит std::bad_variant_access
} catch (const std::bad_variant_access&) {
std::cerr << "Неверный тип!\n";
}

auto* ptr = std::get_if<std::string>(&v); // nullptr если не string



🐾 std::visit — главная фишка:

std::variant<int, double, std::string> v = 42;

// Обработка всех возможных типов
std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;

if constexpr (std::is_same_v<T, int>) {
std::cout << "int: " << arg << '\n';
} else if constexpr (std::is_same_v<T, double>) {
std::cout << "double: " << arg << '\n';
} else {
std::cout << "string: " << arg << '\n';
}
}, v);



🍪 Перегруженный visitor (C++17 трюк):

cpptemplate<class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};

template<class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;

// Элегантная обработка!
std::visit(overloaded{
[](int i) { std::cout << "int: " << i << '\n'; },
[](double d) { std::cout << "double: " << d << '\n'; },
[](const std::string& s) { std::cout << "string: " << s << '\n'; }
}, v);



✏️ Пример: Обработка ошибок

template<typename T>
using Result = std::variant<T, std::string>; // Value или Error

Result<int> divide(int a, int b) {
if (b == 0) return "Division by zero";
return a / b;
}

auto result = divide(10, 0);
std::visit(overloaded{
[](int value) { std::cout << "Result: " << value << '\n'; },
[](const std::string& err) { std::cerr << "Error: " << err << '\n'; }
}, result);



❗️ Важно:

std::variant никогда не пустой (кроме исключительных ситуаций). Первый тип должен быть конструируемым по умолчанию.


❗️std::any:

Используйте std::variant когда набор типов известен. std::any — для действительно произвольных типов.


Библиотека C/C++ разработчика

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥42



tgoop.com/cppproglib/6104
Create:
Last Update:

👁 std::variant — типобезопасный union

std::variant (C++17) — это union, который знает свой текущий тип и гарантирует безопасность.


🐤 Старый подход:

// C-style union — опасно!
union Data {
int i;
double d;
char* str;
};

Data data;
data.i = 42;
std::cout << data.d; // Читаем не то, что записали



🐸 Современный подход:

std::variant<int, double, std::string> data;

data = 42; // Хранит int
data = 3.14; // Теперь хранит double
data = "hello"; // Теперь хранит string

// Безопасное получение значения
if (auto* val = std::get_if<int>(&data)) {
std::cout << "int: " << *val << '\n';
}



🥨 Базовые операции:

std::variant<int, std::string, double> v;

// Установка значения
v = 100;
v = "text";
v.emplace<std::string>("constructed in place");

// Проверка текущего типа
std::cout << v.index(); // Индекс типа: 0, 1, или 2

if (std::holds_alternative<int>(v)) {
std::cout << "Содержит int\n";
}

// Получение значения
try {
auto val = std::get<int>(v); // Бросит std::bad_variant_access
} catch (const std::bad_variant_access&) {
std::cerr << "Неверный тип!\n";
}

auto* ptr = std::get_if<std::string>(&v); // nullptr если не string



🐾 std::visit — главная фишка:

std::variant<int, double, std::string> v = 42;

// Обработка всех возможных типов
std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;

if constexpr (std::is_same_v<T, int>) {
std::cout << "int: " << arg << '\n';
} else if constexpr (std::is_same_v<T, double>) {
std::cout << "double: " << arg << '\n';
} else {
std::cout << "string: " << arg << '\n';
}
}, v);



🍪 Перегруженный visitor (C++17 трюк):

cpptemplate<class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};

template<class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;

// Элегантная обработка!
std::visit(overloaded{
[](int i) { std::cout << "int: " << i << '\n'; },
[](double d) { std::cout << "double: " << d << '\n'; },
[](const std::string& s) { std::cout << "string: " << s << '\n'; }
}, v);



✏️ Пример: Обработка ошибок

template<typename T>
using Result = std::variant<T, std::string>; // Value или Error

Result<int> divide(int a, int b) {
if (b == 0) return "Division by zero";
return a / b;
}

auto result = divide(10, 0);
std::visit(overloaded{
[](int value) { std::cout << "Result: " << value << '\n'; },
[](const std::string& err) { std::cerr << "Error: " << err << '\n'; }
}, result);



❗️ Важно:

std::variant никогда не пустой (кроме исключительных ситуаций). Первый тип должен быть конструируемым по умолчанию.


❗️std::any:

Используйте std::variant когда набор типов известен. std::any — для действительно произвольных типов.


Библиотека C/C++ разработчика

#буст

BY Библиотека C/C++ разработчика | cpp, boost, qt


Share with your friend now:
tgoop.com/cppproglib/6104

View MORE
Open in Telegram


Telegram News

Date: |

How to create a business channel on Telegram? (Tutorial) 3How to create a Telegram channel? So far, more than a dozen different members have contributed to the group, posting voice notes of themselves screaming, yelling, groaning, and wailing in various pitches and rhythms. The best encrypted messaging apps The visual aspect of channels is very critical. In fact, design is the first thing that a potential subscriber pays attention to, even though unconsciously.
from us


Telegram Библиотека C/C++ разработчика | cpp, boost, qt
FROM American