Namespaces
Variants

std::optional<T>::optional

De es.cppreference.net
 
 
Biblioteca de utilidades
Soporte del lenguaje
Soporte de tipos (tipos básicos, RTTI)
Macros de prueba de características de la biblioteca (C++20)
Utilidades de programa
Funciones variádicas
Soporte de corrutinas (C++20)
Soporte de contratos (C++26)
Comparación de tres vías
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Utilidades generales
Operadores relacionales (obsoleto en C++20)
 
 
constexpr optional() noexcept;
constexpr optional( std::nullopt_t ) noexcept;
(1) (desde C++17)
constexpr optional( const optional& other );
(2) (desde C++17)
constexpr optional( optional&& other ) noexcept(/* see below */);
(3) (desde C++17)
template < class U >
optional( const optional<U>& other );
(4) (desde C++17)
(constexpr desde C++20)
(condicionalmente explícito)
template < class U >
optional( optional<U>&& other );
(5) (desde C++17)
(constexpr desde C++20)
(condicionalmente explícito)
template< class... Args >
constexpr explicit optional( std::in_place_t, Args&&... args );
(6) (desde C++17)
template< class U, class... Args >
constexpr explicit optional( std::in_place_t,
                             std::initializer_list<U> ilist,
                             Args&&... args );
(7) (desde C++17)
template < class U = std::remove_cv_t<T> >
constexpr optional( U&& value );
(8) (desde C++17)
(condicionalmente explícito)

Construye un nuevo objeto optional.

1) Construye un objeto que no contiene un valor.
2) Constructor de copia: Si other contiene un valor, inicializa el valor contenido como si inicializara directamente (pero no mediante inicialización directa de lista) un objeto de tipo T con la expresión *other. Si other no contiene un valor, construye un objeto que no contiene un valor.
  • Este constructor se define como eliminado si std::is_copy_constructible_v<T> es false.
  • Es un constructor trivial si std::is_trivially_copy_constructible_v<T> es true.
3) Constructor de movimiento: Si other contiene un valor, inicializa el valor contenido como si inicializara directamente (pero no mediante inicialización directa de lista) un objeto de tipo T con la expresión std::move(*other) y no hace que other esté vacío: un std::optional movido todavía contiene un valor, pero el valor en sí mismo ha sido movido. Si other no contiene un valor, construye un objeto que no contiene un valor.
  • Este constructor no participa en la resolución de sobrecarga a menos que std::is_move_constructible_v<T> sea true.
  • Es un constructor trivial si std::is_trivially_move_constructible_v<T> es true.
4) Constructor de copia convertidor: Si other no contiene un valor, construye un objeto optional que no contiene un valor. En caso contrario, construye un objeto optional que contiene un valor, inicializado como si inicializara directamente (pero no mediante inicialización directa de lista) un objeto de tipo T con la expresión *other.
  • Este constructor no participa en la resolución de sobrecarga a menos que se cumplan las siguientes condiciones:
    • std::is_constructible_v<T, const U&> es true.
    • Si T no es (posiblemente cv-cualificado) bool, T no es construible ni convertible desde ninguna expresión de tipo (posiblemente const) std::optional<U>, es decir, converts_from_any_cvref<T, std::optional<U>> es false, donde converts_from_any_cvref se describe a continuación.
  • Este constructor es explicit si y solo si std::is_convertible_v<const U&, T> es false.
5) Constructor de movimiento convertidor: Si other no contiene un valor, construye un objeto optional que no contiene un valor. En caso contrario, construye un objeto optional que contiene un valor, inicializado como si inicializara directamente (pero no mediante inicialización directa de lista) un objeto de tipo T con la expresión std::move(*other).
  • Este constructor no participa en la resolución de sobrecarga a menos que se cumplan las siguientes condiciones:
    • std::is_constructible_v<T, U&&> es true.
    • Si T no es (posiblemente cv-cualificado) bool, T no es construible ni convertible desde ninguna expresión de tipo (posiblemente const) std::optional<U>, es decir, converts_from_any_cvref<T, std::optional<U>> es false, donde converts_from_any_cvref se describe a continuación.
  • Este constructor es explicit si y solo si std::is_convertible_v<U&&, T> es false.
6) Construye un objeto optional que contiene un valor, inicializado como si inicializara directamente (pero no mediante inicialización directa de lista) un objeto de tipo T a partir de los argumentos std::forward<Args>(args)....
  • Si el constructor seleccionado de T es un constructor constexpr, este constructor es un constructor constexpr.
  • La función no participa en la resolución de sobrecarga a menos que std::is_constructible_v<T, Args...> sea true.
7) Construye un objeto optional que contiene un valor, inicializado como si inicializara directamente (pero no mediante inicialización directa de lista) un objeto de tipo T a partir de los argumentos ilist, std::forward<Args>(args)....
  • Si el constructor seleccionado de T es un constructor constexpr, este constructor es un constructor constexpr.
  • La función no participa en la resolución de sobrecarga a menos que std::is_constructible_v<T, std::initializer_list<U>&, Args...> sea true.
8) Construye un objeto optional que contiene un valor, inicializado como si inicializara directamente (pero no mediante inicialización directa de lista) un objeto de tipo T con la expresión std::forward<U>(value).
  • Si el constructor seleccionado de T es un constructor constexpr, este constructor es un constructor constexpr.
  • Este constructor no participa en la resolución de sobrecarga a menos que se cumplan las siguientes condiciones:
    • std::is_constructible_v<T, U&&> es true.
    • std::decay_t<U>(hasta C++20)std::remove_cvref_t<U>(desde C++20) no es ni std::in_place_t ni std::optional<T>.
    • Si T es (posiblemente cv-cualificado) bool, std::decay_t<U>(hasta C++20)std::remove_cvref_t<U>(desde C++20) no es una especialización de std::optional.
  • Este constructor es explicit si y solo si std::is_convertible_v<U&&, T> es false.

La plantilla de variable auxiliar converts_from_any_cvref es equivalente a:

template< class T, class W >
constexpr bool converts_from_any_cvref =
    std::disjunction_v<std::is_constructible<T, W&>, std::is_convertible<W&, T>,
                       std::is_constructible<T, W>, std::is_convertible<W, T>,
                       std::is_constructible<T, const W&>, std::is_convertible<const W&, T>,
                       std::is_constructible<T, const W>, std::is_convertible<const W, T>>;

Parámetros

other - otro objeto optional cuyo valor contenido es copiado
value - valor con el cual inicializar el valor contenido
args... - argumentos con los cuales inicializar el valor contenido
ilist - lista de inicialización con la cual inicializar el valor contenido

Excepciones

3) Lanza cualquier excepción lanzada por el constructor de T .
4) Lanza cualquier excepción lanzada por el constructor de T . Tiene la siguiente
noexcept especificación:
noexcept ( std:: is_nothrow_move_constructible < T > :: value )
5-9) Lanza cualquier excepción lanzada por el constructor de T .

Notas

Antes de la resolución de LWG issue 3836 , construir un std:: optional < bool > desde std:: optional < U > seleccionaría la sobrecarga ( 9 ) en lugar de las sobrecargas ( 5,6 ) si U no es bool . Esto se debe a que las sobrecargas ( 5,6 ) no participaban en la resolución de sobrecarga si T ( bool en este caso) puede ser construido o convertido desde std:: optional < U > , pero std::optional::operator bool hace posible la conversión para cualquier U .

Como resultado, el std:: optional < bool > construido siempre contiene un valor. Ese valor se determina por si el objeto std:: optional < U > proporcionado contiene un valor, en lugar del valor bool inicializado directamente desde el valor contenido:

std::optional<bool> op_false(false);
std::optional<int> op_zero(0);
std::optional<int> from_bool(op_false); // OK: contiene 0 (inicializado desde false)
std::optional<bool> from_int(op_zero);  // DEFECTO (LWG 3836): contiene true porque
                                        // op_zero contiene un valor, incluso si inicializar
                                        // bool desde ese valor da false
Macro de prueba de características Valor Std Característica
__cpp_lib_optional 202106L (C++20)
(DR20)
Completamente constexpr ( 5,6 )

Ejemplo

#include <iostream>
#include <optional>
#include <string>
int main()
{
    std::optional<int> o1, // vacío
                       o2 = 1, // inicializado desde valor R
                       o3 = o2; // constructor de copia
    // llama al constructor std::string( initializer_list<CharT> )
    std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'});
    // llama al constructor std::string( size_type count, CharT ch )
    std::optional<std::string> o5(std::in_place, 3, 'A');
    // Construido por movimiento desde std::string usando guía de deducción para seleccionar el tipo
    std::optional o6(std::string{"deduction"});
    std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5  << ' ' << *o6 << '\n';
}

Salida:

1 1 abc AAA deduction

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Se aplica a Comportamiento publicado Comportamiento correcto
LWG 3836 C++17 al construir un std:: optional < bool >
desde std:: optional < U > , la resolución de sobrecarga
seleccionaría la sobrecarga ( 9 ) si U no es bool
siempre selecciona el
constructor de copia/movimiento
de conversión en este caso
LWG 3886 C++17 el argumento de plantilla por defecto de la sobrecarga ( 9 ) era T cambiado a std:: remove_cv_t < T >
P0602R4 C++17 los constructores de copia/movimiento podrían no ser triviales
incluso si el constructor subyacente es trivial
requerido para
propagar trivialidad
P2231R1 C++20 las sobrecargas ( 5,6 ) desde otro std::optional no eran constexpr convertidas en constexpr

Véase también

crea un objeto optional
(plantilla de función)