Namespaces
Variants

std::optional<T>::optional

cppreference.net에서
 
 
유틸리티 라이브러리
일반 유틸리티
관계 연산자 (C++20에서 폐지됨)
정수 비교 함수
(C++20)(C++20)(C++20)    
(C++20)
swap 및 타입 연산
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
공통 어휘 타입
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
constexpr optional() noexcept;
constexpr optional( std::nullopt_t ) noexcept;
(1) (C++17부터)
constexpr optional( const optional& other );
(2) (C++17부터)
constexpr optional( optional&& other ) noexcept(/* see below */);
(3) (C++17부터)
template < class U >
optional( const optional<U>& other );
(4) (C++17부터)
(C++20부터 constexpr)
(조건부 명시적)
template < class U >
optional( optional<U>&& other );
(5) (C++17부터)
(C++20부터 constexpr)
(조건부 명시적)
template< class... Args >
constexpr explicit optional( std::in_place_t, Args&&... args );
(6) (C++17부터)
template< class U, class... Args >
constexpr explicit optional( std::in_place_t,
                             std::initializer_list<U> ilist,
                             Args&&... args );
(7) (C++17부터)
template < class U = std::remove_cv_t<T> >
constexpr optional( U&& value );
(8) (C++17부터)
(조건부 명시적)

새로운 optional 객체를 생성합니다.

1) 값을 포함하지 않는 객체를 생성합니다.
2) 복사 생성자: other이 값을 포함하면, 포함된 값을 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 표현식 *other으로 초기화하는 것처럼 초기화합니다. other이 값을 포함하지 않으면, 값을 포함하지 않는 객체를 생성합니다.
  • 이 생성자는 std::is_copy_constructible_v<T>이 false인 경우 삭제된 것으로 정의됩니다.
  • 이는 std::is_trivially_copy_constructible_v<T>이 true인 경우 사소한 생성자입니다.
3) 이동 생성자: other이 값을 포함하면, 포함된 값을 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 표현식 std::move(*other)으로 초기화하는 것처럼 초기화하고, 을 비우지 other않습니다: 이동된 std::optional은 여전히 값을 포함하지만, 값 자체는 이동됩니다. other이 값을 포함하지 않으면, 값을 포함하지 않는 객체를 생성합니다.
  • 이 생성자는 std::is_move_constructible_v<T>이 true인 경우에만 오버로드 해결에 참여합니다.
  • 이는 std::is_trivially_move_constructible_v<T>이 true인 경우 사소한 생성자입니다.
4) 변환 복사 생성자: other이 값을 포함하지 않으면, 값을 포함하지 않는 optional 객체를 생성합니다. 그렇지 않으면, 값을 포함하는 optional 객체를 생성하며, 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 표현식 *other으로 초기화하는 것처럼 초기화됩니다.
  • 이 생성자는 다음 조건이 충족되는 경우에만 오버로드 해결에 참여합니다:
    • std::is_constructible_v<T, const U&>은 true입니다.
    • 만약 T이 (cv 한정될 수 있는) bool이 아닌 경우, T은 (가능한 const) std::optional<U> 타입의 어떤 표현식으로부터도 생성 가능하거나 변환 가능하지 않습니다. 즉, converts_from_any_cvref<T, std::optional<U>>은 false이며, 여기서 converts_from_any_cvref은 아래에 설명됩니다.
  • 이 생성자는 explicit인 경우에만 std::is_convertible_v<const U&, T>이 false입니다.
5) 변환 이동 생성자: other이 값을 포함하지 않으면, 값을 포함하지 않는 optional 객체를 생성합니다. 그렇지 않으면, 값을 포함하는 optional 객체를 생성하며, 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 표현식 std::move(*other)으로 초기화하는 것처럼 초기화됩니다.
  • 이 생성자는 다음 조건이 충족되는 경우에만 오버로드 해결에 참여합니다:
    • std::is_constructible_v<T, U&&>은 true입니다.
    • 만약 T이 (cv 한정될 수 있는) bool이 아닌 경우, T은 (가능한 const) std::optional<U> 타입의 어떤 표현식으로부터도 생성 가능하거나 변환 가능하지 않습니다. 즉, converts_from_any_cvref<T, std::optional<U>>은 false이며, 여기서 converts_from_any_cvref은 아래에 설명됩니다.
  • 이 생성자는 explicit인 경우에만 std::is_convertible_v<U&&, T>이 false입니다.
6) 값을 포함하는 optional 객체를 생성하며, 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 인수 std::forward<Args>(args)...로부터 초기화하는 것처럼 초기화됩니다.
  • 선택된 T의 생성자가 constexpr 생성자인 경우, 이 생성자는 constexpr 생성자입니다.
  • 함수는 std::is_constructible_v<T, Args...>이 true인 경우에만 오버로드 해결에 참여합니다.
7) 값을 포함하는 optional 객체를 생성하며, 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 인수 ilist, std::forward<Args>(args)...로부터 초기화하는 것처럼 초기화됩니다.
  • 선택된 T의 생성자가 constexpr 생성자인 경우, 이 생성자는 constexpr 생성자입니다.
  • 함수는 std::is_constructible_v<T, std::initializer_list<U>&, Args...>이 true인 경우에만 오버로드 해결에 참여합니다.
8) 값을 포함하는 optional 객체를 생성하며, 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 표현식 std::forward<U>(value)으로 초기화하는 것처럼 초기화됩니다.
  • 선택된 T의 생성자가 constexpr 생성자인 경우, 이 생성자는 constexpr 생성자입니다.
  • 이 생성자는 다음 조건이 충족되는 경우에만 오버로드 해결에 참여합니다:
    • std::is_constructible_v<T, U&&>은 true입니다.
    • std::decay_t<U>(C++20까지)std::remove_cvref_t<U>(C++20부터)은 std::in_place_t도 std::optional<T>도 아닙니다.
    • 만약 T이 (cv 한정될 수 있는) bool인 경우, std::decay_t<U>(C++20까지)std::remove_cvref_t<U>(C++20부터)은 std::optional의 특수화가 아닙니다.
  • 이 생성자는 explicit인 경우에만 std::is_convertible_v<U&&, T>이 false입니다.

도우미 변수 템플릿 converts_from_any_cvref은 다음과 동일합니다:

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>>;

매개변수

other - 다른 optional 객체로부터 포함된 값을 복사
value - 포함된 값을 초기화하는 데 사용할 값
args... - 포함된 값을 초기화하는 데 사용할 인수들
ilist - 포함된 값을 초기화하는 데 사용할 초기화자 리스트

예외

3) T 의 생성자가 던지는 모든 예외를 throw합니다.
4) T 의 생성자가 던지는 모든 예외를 전파합니다. 다음과 같은
noexcept 명세를 가집니다:
noexcept ( std:: is_nothrow_move_constructible < T > :: value )
5-9) T 의 생성자가 던지는 모든 예외를 전파합니다.

참고 사항

LWG 이슈 3836 이 해결되기 전에는, std:: optional < bool > 를 std:: optional < U > 로부터 생성할 때 U 가 bool 이 아닌 경우, 오버로드 ( 5,6 ) 대신 오버로드 ( 9 ) 가 선택되었습니다. 이는 오버로드 ( 5,6 ) 가 T (이 경우 bool )가 std:: optional < U > 로부터 생성되거나 변환될 수 있는 경우에만 오버로드 해결에 참여했지만, std::optional::operator bool 가 모든 U 에 대해 변환을 가능하게 만들었기 때문입니다.

결과적으로, 생성된 std:: optional < bool > 는 항상 값을 포함합니다. 해당 값은 제공된 std:: optional < U > 객체가 값을 포함하는지 여부에 의해 결정되며, 포함된 값으로부터 직접 초기화된 bool 값 자체에 의해 결정되는 것은 아닙니다:

std::optional<bool> op_false(false);
std::optional<int> op_zero(0);
std::optional<int> from_bool(op_false); // OK: 0을 포함함 (false로부터 초기화됨)
std::optional<bool> from_int(op_zero);  // 결함 (LWG 3836): true를 포함함. 왜냐하면
                                        // op_zero가 값을 포함하고 있기 때문이며,
                                        // 해당 값으로 bool을 초기화하면 false가 되더라도
기능 테스트 매크로 값 표준 기능
__cpp_lib_optional 202106L (C++20)
(DR20)
완전한 constexpr ( 5,6 )

예제

#include <iostream>
#include <optional>
#include <string>
int main()
{
    std::optional<int> o1, // 비어 있음
                       o2 = 1, // rvalue로부터 초기화
                       o3 = o2; // 복사 생성자
    // std::string( initializer_list<CharT> ) 생성자 호출
    std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'});
    // std::string( size_type count, CharT ch ) 생성자 호출
    std::optional<std::string> o5(std::in_place, 3, 'A');
    // 타입 추론 가이드를 사용하여 std::string으로부터 이동 생성
    std::optional o6(std::string{"deduction"});
    std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5  << ' ' << *o6 << '\n';
}

출력:

1 1 abc AAA deduction

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 수정된 동작
LWG 3836 C++17 std:: optional < bool > 를 std:: optional < U > 에서 생성할 때
U 가 bool 가 아닌 경우 오버로드 ( 9 ) 선택
이 경우 항상 변환
복사/이동 생성자를
선택하도록 수정
LWG 3886 C++17 오버로드 ( 9 ) 의 기본 템플릿 인자가 T 였음 std:: remove_cv_t < T > 로 변경
P0602R4 C++17 기본 생성자가 trivial해도
복사/이동 생성자가 trivial하지 않을 수 있음
triviality 전파를
요구하도록 수정
P2231R1 C++20 다른 std::optional 에서의 오버로드 ( 5,6 ) 가 constexpr 가 아니었음 constexpr 로 변경

참고 항목

optional 객체를 생성합니다
(함수 템플릿)