C++26stlexpert
std::variant::and_then (C++26 Evolution)
C++26 · The Next Frontier · Compiler flag: -std=c++26
Explanation
Enhanced `and_then` for `std::variant` with improved chaining.
Real-World Scenario
Transform variant data in a game’s event system.
Quick Snippet
snippet.cpp
#include <variant> auto result = var.and_then([](int x) { return std::variant<int>{x * x}; });Full Example
variant_and_then.cpp
// CodeNebula - C++26 Example: std::variant::and_then in C++26 Context
// Compile: g++ -std=c++26 -Wall -Wextra -o example variant_and_then.cpp
// Note: Requires C++26 compiler support
#include <iostream>
#include <variant>
#include <string>
// C++26 proposes monadic operations for std::variant:
// variant.visit(f) - member visit (replaces free std::visit)
// transform(var,f) - map the held value
// These enable composable pipelines similar to optional/expected.
namespace var_sim {
template <typename V, typename F>
auto visit(V&& var, F&& f) {
return std::visit(std::forward<F>(f), std::forward<V>(var));
}
template <typename... Ts, typename F>
auto transform(const std::variant<Ts...>& var, F f) {
return std::visit([&](const auto& v) -> std::variant<Ts...> {
return f(v);
}, var);
}
}
using Value = std::variant<int, double, std::string>;
std::string describe(const Value& v) {
return var_sim::visit(v, [](const auto& val) -> std::string {
using T = std::decay_t<decltype(val)>;
if constexpr (std::is_same_v<T, int>) return "int(" + std::to_string(val) + ")";
else if constexpr (std::is_same_v<T, double>) return "double(" + std::to_string(val) + ")";
else return "string(\"" + val + "\")";
});
}
int main() {
std::cout << "--- std::variant Monadic Ops (C++26) ---\n\n";
Value v1 = 42; Value v2 = 3.14; Value v3 = std::string("hello");
std::cout << "v1: " << describe(v1) << "\n";
std::cout << "v2: " << describe(v2) << "\n";
std::cout << "v3: " << describe(v3) << "\n";
// Transform: double numeric values
std::cout << "\n--- Transform ---\n";
auto doubled = var_sim::transform(v1, [](const auto& val) -> Value {
using T = std::decay_t<decltype(val)>;
if constexpr (std::is_arithmetic_v<T>) return static_cast<T>(val * 2);
else return val;
});
std::cout << "transform(42, *2) = " << describe(doubled) << "\n";
// Visitor dispatch
std::cout << "\n--- Dispatch ---\n";
for (const auto& v : {Value{10}, Value{2.5}, Value{std::string("C++26")}}) {
var_sim::visit(v, [](const auto& val) {
using T = std::decay_t<decltype(val)>;
if constexpr (std::is_same_v<T, int>) std::cout << " Int: " << val << "\n";
else if constexpr (std::is_same_v<T, double>) std::cout << " Dbl: " << val << "\n";
else std::cout << " Str: " << val << "\n";
});
}
std::cout << "\nC++26: variant gains composable monadic operations.\n";
return 0;
}
// Expected output:
// --- std::variant Monadic Ops (C++26) ---
//
// v1: int(42)
// v2: double(3.140000)
// v3: string("hello")
//
// --- Transform ---
// transform(42, *2) = int(84)
//
// --- Dispatch ---
// Int: 10
// Dbl: 2.5
// Str: C++26
//
// C++26: variant gains composable monadic operations.
Run command
g++ -std=c++26 -Wall -Wextra -o example variant_and_then.cpp