Namespaces
Variants

std::optional<T>:: optional

From cppreference.net
Utilities library
constexpr optional ( ) noexcept ;
(1) (desde C++17)
constexpr optional ( std:: nullopt_t ) noexcept ;
(2) (desde C++17)
constexpr optional ( const optional & other ) ;
(3) (desde C++17)
constexpr optional ( optional && other ) noexcept ( /* ver más abajo */ ) ;
(4) (desde C++17)
template < class U >
optional ( const optional < U > & other ) ;
(5) (desde C++17)
(constexpr desde C++20)
(condicionalmente explícito)
template < class U >
optional ( optional < U > && other ) ;
(6) (desde C++17)
(constexpr desde C++20)
(condicionalmente explícito)
template < class ... Args >
constexpr explicit optional ( std:: in_place_t , Args && ... args ) ;
(7) (desde C++17)
template < class U, class ... Args >

constexpr explicit optional ( std:: in_place_t ,
std:: initializer_list < U > ilist,

Args && ... args ) ;
(8) (desde C++17)
template < class U = std:: remove_cv_t < T > >
constexpr optional ( U && value ) ;
(9) (desde C++17)
(condicionalmente explícito)

Construye un nuevo objeto optional .

Contenidos

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

Efectos

Sobrecarga Método de inicialización Inicializador para el valor contenido has_value() después de la construcción
( 1 ) N/A - false
( 2 )
( 3 ) Directa (no-lista) * other other. has_value ( )
  • Si false , el valor contenido no se inicializa.
( 4 ) std :: move ( * other )
( 5 ) * other
( 6 ) std :: move ( * other )
( 7 ) std:: forward < Args > ( args ) ... true
( 8 ) ilist, std:: forward < Args > ( args ) ...
( 9 ) std:: forward < U > ( value )

Restricciones e información complementaria

3) Si std:: is_copy_constructible_v < T > es false , el constructor se define como eliminado.
Si std:: is_trivially_copy_constructible_v < T > es true , el constructor es trivial.
4) Esta sobrecarga participa en la resolución de sobrecarga solo si std:: is_move_constructible_v < T > es true .
Si std:: is_trivially_move_constructible_v < T > es true , el constructor es trivial.
5) Esta sobrecarga participa en la resolución de sobrecarga solo si se satisfacen todas las siguientes condiciones:
Esta sobrecarga se declara como si fuera con explicit ( ! std:: is_convertible_v < const U & , T > ) .
6) Esta sobrecarga participa en la resolución de sobrecarga solo si se satisfacen todas las siguientes condiciones:
Esta sobrecarga se declara como si fuera con explicit ( ! std:: is_convertible_v < U, T > ) .
7) Esta sobrecarga participa en la resolución de sobrecarga solo si std:: is_constructible_v < T, Args... > es true .
Si T ’s constructor seleccionado para la inicialización es un constexpr constructor, este constructor también es un constexpr constructor.
8) Esta sobrecarga participa en la resolución de sobrecarga solo si std:: is_constructible_v < T, std:: initializer_list < U > & , Args... > es true .
Si T ’s constructor seleccionado para la inicialización es un constexpr constructor, este constructor también es un constexpr constructor.
9) Esta sobrecarga participa en la resolución de sobrecarga solo si se satisfacen todas las siguientes condiciones:
Esta sobrecarga se declara como si fuera con explicit ( ! std:: is_convertible_v < U, T > ) .
Si T ’s constructor seleccionado para la inicialización es un constexpr constructor, este constructor también es un constexpr constructor.
  1. 1.0 1.1 En otras palabras, T no es construible ni convertible desde ninguna expresión de tipo (posiblemente calificado con const) std:: optional < U >

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 .

Guías de deducción

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)