Tuple, variant and function-trait machinery all need the same primitive: take the I-th type out of a pack. There is no pack indexing in the language — you walk the pack by peeling one type per step. The error case matters as much as the happy path: an out-of-range index must not silently produce something.
Implement NthType<I, Ts...>::type — the I-th type of the pack (zero-based). NthType<1, int, double, char> is double. Asking for an index past the end must be a COMPILE error, not a fallback type.
Two specializations are enough: I == 0 takes the head; any other I drops the head and asks for I - 1.
Leave the primary template declared but undefined — running out of types then hits it and fails to compile, exactly as required.
Hit Submit (or ⌘/Ctrl + ↵) — test results will show up here.