Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Data Types  ›  Lesson

Dynamic Typing with variant and any

Dynamic Typing 12 minC++ is statically typed, but std::variant holds one of a fixed list of types and std::any holds a value of any type, letting a single variable carry different types at run time with checked access.

Dynamic Typing with variant and any

Rocket Run's settings screen has a volume (a whole number), a brightness (a decimal) and a nickname (text). You would like one map from setting name to value. But C++ variables have one fixed type. The standard library solves this without giving up safety: the container has a fixed type, and the value inside can vary at run time.

The rule

Known list of types: variant. Truly anything: any. Both check on access.

In a dynamically typed language like Python, a variable can hold an int now and a string later. C++ is static, so it offers two types that carry that flexibility inside them.

std::variant (header <variant>) holds exactly one value from a list you name:

using Setting = std::variant<int, double, std::string>;

Setting volume = 80;
Setting nickname = std::string("Nova");

if (std::holds_alternative<int>(volume)) {
    int v = std::get<int>(volume);    // 80
}
nickname = 3;                         // now it holds an int

Asking std::get for a type the variant does not currently hold throws std::bad_variant_access. To handle every possible type in one place, std::visit calls your code with whichever value is inside.

std::any (header <any>) holds a single value of any copyable type:

std::any extra = 5;
int n = std::any_cast<int>(extra);    // 5
double d = std::any_cast<double>(extra);  // throws std::bad_any_cast

any_cast needs the exact stored type: an int is not quietly converted to a double.

Old C code used void* for this job. It remembers no type at all, so a wrong guess is undefined behaviour rather than a clean exception.

The shortcut

Ask "Can I list every type it might hold?" Yes: std::variant, and the compiler knows the list. No: std::any. If you cannot answer either way, rethink the design.

Reading the volume safelyStep 1 of 4
  1. Choose the container

    Volume, brightness and nickname: three known types. Use std::variant<int, double, std::string>.

Drills

Answer fast — trust the rule.

quick drill

After std::variant<int, std::string> v = 42; v = std::string("Nova");, what does std::holds_alternative<std::string>(v) return?

quick drill

What does std::get<int>(v) do when v currently holds a std::string?

quick drill

A setting is always an int, a double or a string. Which type fits best?

quick drill

What does std::any a = 5; std::any_cast<double>(a); do?

Remember

  • Known list of types: std::variant. Truly anything: std::any. Both check on access.
  • Shortcut: "Can I list every type it might hold?"
  • Trap: a wrong get or any_cast throws; check first, and avoid void*.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainStoring game settings

Rocket Run's settings screen stores volume as an int, brightness as a double and nickname as a string, all in one map. Explain whether you would use std::variant or std::any for the value type, how you would read a value safely, and what happens if you ask for the wrong type.