std:: variant
|
헤더 파일에 정의됨
<variant>
|
||
|
template
<
class
...
Types
>
class variant ; |
(C++17부터) | |
클래스 템플릿
std::variant
는 타입 안전
union
을 나타냅니다.
variant
의 인스턴스는 언제든지 대체 타입 중 하나의 값을 보유하거나, 오류 발생 시에는 값을 보유하지 않습니다(이 상태는 달성하기 어렵습니다.
valueless_by_exception
참조).
union과 마찬가지로, variant가 객체 타입
T
의 값을 보유하는 경우,
T
객체는
내부에 중첩되어
variant
객체 안에 위치합니다.
variant는 참조, 배열 또는 void 타입을 보유할 수 없습니다.
variant은 동일한 타입을 여러 번 보유하는 것이 허용되며, 동일한 타입의 서로 다른 cv 한정 버전을 보유할 수 있습니다.
aggregate initialization 동안의 union 동작과 일관되게, 기본 생성된 variant는 첫 번째 alternative의 값을 보유합니다. 단, 해당 alternative가 기본 생성 가능하지 않은 경우는 예외입니다(이 경우 variant도 기본 생성 가능하지 않습니다). 헬퍼 클래스 std::monostate 를 사용하면 이러한 variant를 기본 생성 가능하게 만들 수 있습니다.
템플릿 인수 없이
std::variant
의 정의를 인스턴스화하는 프로그램은 형식이 잘못되었습니다.
std
::
variant
<
std::
monostate
>
를 대신 사용할 수 있습니다.
프로그램이 explicit 또는 partial specialization을 선언하는 경우, 그 프로그램은 진단 없이 잘못된 형식입니다.
목차 |
템플릿 매개변수
| Types | - | 이 variant에 저장될 수 있는 타입들. 모든 타입은 Destructible 요구사항을 충족해야 합니다 (특히, 배열 타입과 비객체 타입은 허용되지 않습니다). |
멤버 함수
variant
객체를 생성한다
(public member function) |
|
variant
와 그 안에 포함된 값을 소멸시킨다
(public member function) |
|
variant
에 값을 할당한다
(public member function) |
|
Observers |
|
variant
가 보유한 대안의 0 기반 인덱스를 반환한다
(public member function) |
|
variant
가 무효 상태인지 확인한다
(public member function) |
|
Modifiers |
|
variant
내에 값을 제자리에서 생성한다
(public member function) |
|
다른
variant
와 교환한다
(public member function) |
|
Visitation |
|
|
(C++26)
|
제공된 함수자를
variant
가 보유한 인수로 호출한다
(public member function) |
비멤버 함수
|
(C++17)
|
하나 이상의
variant
가 보유한 인자들로 제공된 함수 객체를 호출합니다
(함수 템플릿) |
|
(C++17)
|
variant
가 현재 주어진 타입을 보유하고 있는지 확인합니다
(함수 템플릿) |
|
(C++17)
|
인덱스나 타입(타입이 고유한 경우)으로 variant의 값을 읽고, 오류 시 예외를 발생시킵니다
(함수 템플릿) |
|
(C++17)
|
인덱스나 타입(고유한 경우)으로 가리키는
variant
의 값에 대한 포인터를 얻고, 오류 시 null을 반환합니다
(함수 템플릿) |
|
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++20)
|
variant
객체를 포함된 값들로 비교합니다
(함수 템플릿) |
|
(C++17)
|
std::swap
알고리즘을 특수화합니다
(함수 템플릿) |
헬퍼 클래스
|
(C++17)
|
기본 생성 불가능한 타입들의
variant
에서 첫 번째 대안으로 사용하기 위한 플레이스홀더 타입
(클래스) |
|
(C++17)
|
variant
값에 대한 잘못된 접근 시 발생하는 예외
(클래스) |
|
(C++17)
|
컴파일 타임에
variant
의 대안 목록 크기를 구함
(클래스 템플릿) (변수 템플릿) |
|
컴파일 타임에 인덱스로 지정된 대안의 타입을 구함
(클래스 템플릿) (별칭 템플릿) |
|
|
(C++17)
|
std::variant
에 대한 해시 지원
(클래스 템플릿 특수화) |
헬퍼 객체
|
(C++17)
|
variant
이 유효하지 않은 상태일 때의 인덱스
(상수) |
참고 사항
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_lib_variant
|
201606L
|
(C++17) |
std::variant
: 타입 안전한 유니온
|
202102L
|
(C++23)
(DR17) |
std::visit
for classes derived from
std::variant
|
|
202106L
|
(C++23)
(DR20) |
완전한
constexpr
std::variant
|
|
202306L
|
(C++26) |
멤버
visit
|
예제
#include <cassert> #include <iostream> #include <string> #include <variant> int main() { std::variant<int, float> v, w; v = 42; // v는 int를 포함 int i = std::get<int>(v); assert(42 == i); // 성공 w = std::get<int>(v); w = std::get<0>(v); // 이전 줄과 동일한 효과 w = v; // 이전 줄과 동일한 효과 // std::get<double>(v); // 오류: [int, float]에 double 없음 // std::get<3>(v); // 오류: 유효한 인덱스 값은 0과 1 try { std::get<float>(w); // w는 float가 아닌 int를 포함: 예외 발생 } catch (const std::bad_variant_access& ex) { std::cout << ex.what() << '\n'; } using namespace std::literals; std::variant<std::string> x("abc"); // 변환 생성자는 모호하지 않을 때 작동 x = "def"; // 변환 할당도 모호하지 않을 때 작동 std::variant<std::string, void const*> y("abc"); // char const*가 전달될 때 void const*로 캐스트 assert(std::holds_alternative<void const*>(y)); // 성공 y = "xyz"s; assert(std::holds_alternative<std::string>(y)); // 성공 }
가능한 출력:
std::get: wrong index for variant
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2901 | C++17 |
std::uses_allocator
특수화가 제공되었으나,
variant
가 할당자를 제대로 지원할 수 없음
|
특수화 제거됨 |
| LWG 3990 | C++17 |
프로그램이
std::variant
의 명시적 또는
부분 특수화를 선언할 수 있었음 |
이 경우 프로그램의 형식이 잘못됨
(진단 메시지 필요 없음) |
| LWG 4141 | C++17 |
저장소 할당 요구사항이
혼란스러웠음 |
포함된 객체는
variant
객체 내에
중첩되어야 함 |
참고 항목
|
인-플레이스 생성 태그
(태그) |
|
|
(C++17)
|
객체를 보유할 수도 있고 보유하지 않을 수도 있는 래퍼
(클래스 템플릿) |
|
(C++17)
|
모든
CopyConstructible
타입의 인스턴스를 보유하는 객체
(클래스) |