utility_tuple_element
utility_tuple_element (튜플 유사 타입의 요소 타입 접근)
std::tuple_element은 튜플 유사(tuple-like) 타입의 특정 위치에 있는 요소의 타입을 컴파일 타임에 알아내기 위한 클래스 템플릿이에요. 이 템플릿은 std::tuple, std::pair, std::array 같은 표준 라이브러리 타입뿐 아니라, 사용자가 직접 정의한 타입에 대해서도 특수화할 수 있어서 구조적 바인딩과 같은 기능을 지원하는 데 사용돼요. 이 페이지에서는 std::tuple_element의 정의, 특수화, 사용 예시를 설명할게요.
출처: cppreference
본문
정의
다음과 같이 <tuple>, <array>, <utility>, <ranges>, <complex> 헤더에 정의되어 있어요.
<tuple> 헤더에 정의됨 |
||
|---|---|---|
<array> 헤더에 정의됨 |
||
<utility> 헤더에 정의됨 |
||
<ranges> 헤더에 정의됨 |
(since C++20) | |
<complex> 헤더에 정의됨 |
(since C++26) |
기본 템플릿은 정의되지 않고, 다음과 같은 형태로 제공돼요.
| template < std :: size_t I , class T > struct tuple_element ; // not defined | (1) | (since C++11) |
|---|---|---|
| template < std :: size_t I , class T > struct tuple_element < I , const T > { using type = typename std :: add_const < typename std :: tuple_element < I , T >:: type >:: type ; }; | (2) | (since C++11) |
| template < std :: size_t I , class T > struct tuple_element < I , volatile T > { using type = typename std :: add_volatile < typename std :: tuple_element < I , T >:: type >:: type ; }; | (3) | (since C++11) (deprecated in C++20) |
| template < std :: size_t I , class T > struct tuple_element < I , const volatile T > { using type = typename std :: add_cv < typename std :: tuple_element < I , T >:: type >:: type ; }; | (4) | (since C++11) (deprecated in C++20) |
이 템플릿은 튜플 유사 타입의 요소 타입에 대한 컴파일 타임 인덱스 접근을 제공해요.
std::tuple_element는 핵심 언어와 상호작용해서, 튜플 유사 경우에 구조적 바인딩(structured binding)을 지원할 수 있어요. (since C++17)
특수화
표준 라이브러리는 다음과 같은 표준 라이브러리 타입에 대한 특수화를 제공해요.
std::tuple_element<std::tuple> (C++11) |
지정된 요소의 타입을 얻습니다 (클래스 템플릿 특수화) [edit] |
|---|---|
std::tuple_element<std::pair> (C++11) |
pair의 요소 타입을 얻습니다 (클래스 템플릿 특수화) [edit] |
std::tuple_element<std::array> (C++11) |
array의 요소 타입을 얻습니다 (클래스 템플릿 특수화) [edit] |
std::tuple_element<std::ranges::subrange> (C++20) |
std::ranges::subrange의 반복자 또는 센티널 타입을 얻습니다 (클래스 템플릿 특수화) [edit] |
std::tuple_element<std::complex> (C++26) |
std::complex의 기본 실수 및 허수 타입을 얻습니다 (클래스 템플릿 특수화) [edit] |
사용자는 프로그램 정의 타입을 튜플 유사하게 만들기 위해 std::tuple_element를 특수화할 수 있어요.
get 함수가 참조 멤버나 하위 객체에 대한 참조를 반환하는 일반적인 경우에는 cv 한정이 없는 타입에 대한 특수화만 사용자 정의하면 돼요.
멤버 타입
| 멤버 타입 | 설명 |
|---|---|
| type | 표준 특수화에서, 튜플 유사 타입 T의 I번째 요소의 타입. 여기서 I는 [ 0 , std :: tuple_size < T >:: value ) 범위에 있어요. |
헬퍼 타입
<tuple> 헤더에 정의됨 |
||
|---|---|---|
| template < std :: size_t I , class T > using tuple_element_t = typename tuple_element < I , T >:: type ; | (since C++14) |
참고 사항
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
| __cpp_lib_tuple_element_t | 201402L | (C++14) | std::tuple_element_t |
예제
#include <array>
#include <cstddef>
#include <iostream>
#include <ranges>
#include <tuple>
#include <type_traits>
#include <utility>
template<typename T1, typename T2, typename T3>
struct Triple
{
T1 t1;
T2 t2;
T3 t3;
};
// A specialization of std::tuple_element for program-defined type Triple:
template<std::size_t I, typename T1, typename T2, typename T3>
struct std::tuple_element<I, Triple<T1, T2, T3>>
{ static_assert(false, "Invalid index"); };
template<typename T1, typename T2, typename T3>
struct std::tuple_element<0, Triple<T1, T2, T3>> { using type = T1; };
template<typename T1, typename T2, typename T3>
struct std::tuple_element<1, Triple<T1, T2, T3>> { using type = T2; };
template<typename T1, typename T2, typename T3>
struct std::tuple_element<2, Triple<T1, T2, T3>> { using type = T3; };
template<typename... Args> struct TripleTypes
{
static_assert(3 == sizeof...(Args), "Expected exactly 3 type names");
template<std::size_t N>
using type = typename std::tuple_element_t<N, Triple<Args...>>;
};
int main()
{
TripleTypes<char, int, float>::type<1> i{42};
std::cout << i << '\n';
using Tri = Triple<int, char, short>; //< Program-defined type
static_assert(std::is_same_v<std::tuple_element_t<0, Tri>, int> &&
std::is_same_v<std::tuple_element_t<1, Tri>, char> &&
std::is_same_v<std::tuple_element_t<2, Tri>, short>);
using Tuple = std::tuple<int, char, short>;
static_assert(std::is_same_v<std::tuple_element_t<0, Tuple>, int> &&
std::is_same_v<std::tuple_element_t<1, Tuple>, char> &&
std::is_same_v<std::tuple_element_t<2, Tuple>, short>);
using Array3 = std::array<int, 3>;
static_assert(std::is_same_v<std::tuple_element_t<0, Array3>, int> &&
std::is_same_v<std::tuple_element_t<1, Array3>, int> &&
std::is_same_v<std::tuple_element_t<2, Array3>, int>);
using Pair = std::pair<Tuple, Tri>;
static_assert(std::is_same_v<std::tuple_element_t<0, Pair>, Tuple> &&
std::is_same_v<std::tuple_element_t<1, Pair>, Tri>);
using Sub = std::ranges::subrange<int*, int*>;
static_assert(std::is_same_v<std::tuple_element_t<0, Sub>, int*> &&
std::is_same_v<std::tuple_element_t<1, Sub>, int*>);
}
출력:
42
결함 보고
다음의 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용되었어요.
| DR | 적용 대상 | 발표된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2212 | C++11 | 일부 헤더에서 cv 타입에 대한 특수화가 요구되지 않아 모호성이 발생했다 | 요구됨 |
같이 보기
| 구조적 바인딩 (C++17) | 초기화자의 하위 객체나 튜플 요소에 지정된 이름을 바인딩합니다 [edit] |
|---|---|
| tuple_size (C++11) | 튜플 유사 타입의 요소 개수를 얻습니다 (클래스 템플릿) [edit] |
| tuple_cat (C++11) | 여러 튜플을 연결하여 튜플을 만듭니다 (함수 템플릿) [edit] |
| tuple_element (C++26) | 튜플 유사 타입의 요소 타입에 대한 리플렉션을 얻습니다 (함수) [edit] |