namespace std {
  template<class... Types>
  class variant {
  public:
    
    constexpr variant() noexcept(see below);
    constexpr variant(const variant&);
    constexpr variant(variant&&) noexcept(see below);
    template<class T>
      constexpr variant(T&&) noexcept(see below);
    template<class T, class... Args>
      constexpr explicit variant(in_place_type_t<T>, Args&&...);
    template<class T, class U, class... Args>
      constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...);
    template<size_t I, class... Args>
      constexpr explicit variant(in_place_index_t<I>, Args&&...);
    template<size_t I, class U, class... Args>
      constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);
    
    constexpr ~variant();
    
    constexpr variant& operator=(const variant&);
    constexpr variant& operator=(variant&&) noexcept(see below);
    template<class T> constexpr variant& operator=(T&&) noexcept(see below);
    
    template<class T, class... Args>
      constexpr T& emplace(Args&&...);
    template<class T, class U, class... Args>
      constexpr T& emplace(initializer_list<U>, Args&&...);
    template<size_t I, class... Args>
      constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
    template<size_t I, class U, class... Args>
      constexpr variant_alternative_t<I, variant<Types...>>&
        emplace(initializer_list<U>, Args&&...);
    
    constexpr bool valueless_by_exception() const noexcept;
    constexpr size_t index() const noexcept;
    
    constexpr void swap(variant&) noexcept(see below);
    
    template<class Self, class Visitor>
      constexpr decltype(auto) visit(this Self&&, Visitor&&);
    template<class R, class Self, class Visitor>
      constexpr R visit(this Self&&, Visitor&&);
  };
}
Any instance of 
variant at any given time either holds a value
of one of its alternative types or holds no value
.When an instance of 
variant holds a value of alternative type 
T,
it means that a value of type 
T, referred to as the 
variant
object's 
contained value, is allocated within the storage of the
variant object
.Implementations are not permitted to use additional storage, such as dynamic
memory, to allocate the contained value
.All types in 
Types shall meet
the 
Cpp17Destructible requirements (Table 
35)
.A program that instantiates the definition of 
variant with
no template arguments is ill-formed
.If a program declares an explicit or partial specialization of 
variant,
the program is ill-formed, no diagnostic required
.