std::optional<T>::optional
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 객체를 생성합니다.
other이 값을 포함하면, 포함된 값을 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 표현식 *other으로 초기화하는 것처럼 초기화합니다. other이 값을 포함하지 않으면, 값을 포함하지 않는 객체를 생성합니다.
- 이 생성자는
std::is_copy_constructible_v<T>이false인 경우 삭제된 것으로 정의됩니다. - 이는
std::is_trivially_copy_constructible_v<T>이true인 경우 사소한 생성자입니다.
other이 값을 포함하면, 포함된 값을 직접 초기화 (단, 직접 목록 초기화는 아님)하여 T 타입의 객체를 표현식 std::move(*other)으로 초기화하는 것처럼 초기화하고, 을 비우지 other않습니다: 이동된 std::optional은 여전히 값을 포함하지만, 값 자체는 이동됩니다. other이 값을 포함하지 않으면, 값을 포함하지 않는 객체를 생성합니다.
- 이 생성자는
std::is_move_constructible_v<T>이true인 경우에만 오버로드 해결에 참여합니다. - 이는
std::is_trivially_move_constructible_v<T>이true인 경우 사소한 생성자입니다.
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입니다.
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입니다.
T 타입의 객체를 인수 std::forward<Args>(args)...로부터 초기화하는 것처럼 초기화됩니다.
- 선택된
T의 생성자가constexpr생성자인 경우, 이 생성자는constexpr생성자입니다. - 함수는
std::is_constructible_v<T, Args...>이true인 경우에만 오버로드 해결에 참여합니다.
T 타입의 객체를 인수 ilist, std::forward<Args>(args)...로부터 초기화하는 것처럼 초기화됩니다.
- 선택된
T의 생성자가constexpr생성자인 경우, 이 생성자는constexpr생성자입니다. - 함수는
std::is_constructible_v<T, std::initializer_list<U>&, Args...>이true인 경우에만 오버로드 해결에 참여합니다.
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 | - | 포함된 값을 초기화하는 데 사용할 초기화자 리스트 |
예외
T
의 생성자가 던지는 모든 예외를 throw합니다.
T
의 생성자가 던지는 모든 예외를 전파합니다. 다음과 같은
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 로 변경 |
참고 항목
|
(C++17)
|
optional
객체를 생성합니다
(함수 템플릿) |