In the descriptions that follow, let i be in the range [0, sizeof...(Types)),
and be the type in Types.

```
constexpr variant() noexcept(see below);
```

```
constexpr variant(const variant& w);
```

```
constexpr variant(variant&& w) noexcept(see below);
```

```
template<class T> constexpr variant(T&& t) noexcept(see below);
```

Let be a type that is determined as follows:
build an imaginary function FUN()
for each alternative type
for which x[] = {std::forward<T>(t)};
is well-formed for some invented variable x.

The overload FUN() selected by overload
resolution for the expression FUN(std::forward<T>(t)) defines
the alternative which is the type of the contained value after
construction.

Constraints:

- sizeof...(Types) is nonzero,
- is_same_v<remove_cvref_t<T>, variant> is false,
- remove_cvref_t<T> is neither a specialization of in_place_type_t nor a specialization of in_place_index_t,
- is_constructible_v<, T> is true, and
- the expression FUN(std::forward<T>(t))
(with FUN being the above-mentioned set of
imaginary functions) is well-formed. [Note:]
variant<string, string> v("abc");

is ill-formed, as both alternative types have an equally viable constructor for the argument. â€”*end note*

```
template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
```

```
template<class T, class U, class... Args>
constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
```

```
template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
```

```
template<size_t I, class U, class... Args>
constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
```