# std::variant_alternative, std::variant_alternative_t

< cpp‎ | utility‎ | variant

定义于头文件 `<variant>` |  |
template <std::size_t I, class T> struct variant_alternative; /* undefined */ | (1) | (C++17 起)
template <std::size_t I, class... Types> struct variant_alternative<I, variant<Types...>>; | (2) | (C++17 起)
template <std::size_t I, class T> class variant_alternative<I, const T>; | (3) | (C++17 起)
template <std::size_t I, class T> class variant_alternative<I, volatile T>; template <std::size_t I, class T> class variant_alternative<I, const volatile T>; | (3) | (C++17 起) (C++20 中弃用)

提供对可有 cv 限定 `variant` 的类型编译时下标访问，将 `variant` 的 cv 限定与可选项的 cv 限定（若存在）相结合。

正式而言，

2) 满足拥有成员 typedef `type` 等于序号为 `I` 的可选项类型的变换特征 (TransformationTrait) 要求
3) 满足拥有成员 typedef `type` 分别为 std::add_const_t<std::variant_alternative_t<I,T>> 、 std::add_volatile_t<std::variant_alternative_t<I,T>> 和 std::add_cv_t<std::variant_alternative_t<I,T>> 的变换特征 (TransformationTrait) 要求

### 成员类型

成员类型 | 定义
type | `variant` 的第 `I` 的可选项的类型，其中 `I` 必须在 `[0, sizeof...(Types))` 中，否则程序为谬构

### 辅助别名模板

template <size_t I, class T> using variant_alternative_t = typename variant_alternative<I, T>::type; |  | (C++17 起)

### 示例

    #include <variant>
    #include <iostream>

    using my_variant = std::variant<int, float>;
    static_assert(std::is_same_v
        <int,   std::variant_alternative_t<0, my_variant>>);
    static_assert(std::is_same_v
        <float, std::variant_alternative_t<1, my_variant>>);
    // variant 类型上的 cv 限定传播给提取出的可选项类型。
    static_assert(std::is_same_v
        <const int, std::variant_alternative_t<0, const my_variant>>);

    int main()
    {
        std::cout << "All static assertions passed\n";
    }

输出：

    All static assertions passed.

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 2974 | C++17 | 越界下标导致未定义行为 | 使之为谬构

### 参阅

variant_size variant_size_v (C++17) | 在编译时获得 `variant` 可选项列表的大小 (类模板) (变量模板)
std::tuple_element<std::tuple> (C++11) | 获得指定元素的类型 (类模板特化)