utility_tuple
utility_tuple (튜플)
std::tuple은 서로 다른 타입의 값들을 고정된 크기로 묶어 저장하는 클래스 템플릿이에요. std::pair의 일반화된 형태로, 여러 값을 하나의 객체로 다루거나 함수에서 여러 값을 한 번에 반환할 때 유용해요. C++11부터 사용할 수 있어요.
출처: cppreference
본문
개요
<tuple> 헤더에 정의돼 있어요.
template < class ... Types > class tuple ; |
(C++11부터) |
클래스 템플릿 std::tuple은 서로 다른 타입의 값들을 고정된 크기로 모아 두는 컬렉션이에요. std::pair의 일반화된 형태예요.
Types에 있는 모든 Ti에 대해 std::is_trivially_destructible<Ti>::value가 true라면, std::tuple의 소멸자는 trivial(사소한) 소멸자예요.
프로그램이 std::tuple의 명시적 특수화나 부분 특수화를 선언하면, 그 프로그램은 ill-formed(잘못된 형식)이며 진단이 필요 없어요.
템플릿 매개변수
Types... |
- | 튜플이 저장하는 요소들의 타입이에요. 빈 목록도 지원돼요. |
|---|
멤버 함수
| (생성자) | 새 튜플을 생성해요 (공개 멤버 함수) |
|---|---|
operator= |
한 튜플의 내용을 다른 튜플에 할당해요 (공개 멤버 함수) |
swap |
두 튜플의 내용을 서로 바꿔요 (공개 멤버 함수) |
비멤버 함수
make_tuple (C++11) |
인자 타입들로 결정되는 타입의 튜플 객체를 생성해요 (함수 템플릿) |
|---|---|
tie (C++11) |
lvalue 참조의 튜플을 만들거나 튜플을 개별 객체로 풀어내요 (함수 템플릿) |
forward_as_tuple (C++11) |
전달 참조(forwarding reference)의 튜플을 생성해요 (함수 템플릿) |
tuple_cat (C++11) |
임의 개수의 튜플들을 이어붙여 튜플을 생성해요 (함수 템플릿) |
get (std::tuple) (C++11) |
튜플의 지정된 요소에 접근해요 (함수 템플릿) |
operator== operator!= operator< operator<= operator> operator>= operator<=> (C++20에서 제거됨) (C++20에서 제거됨) (C++20에서 제거됨) (C++20에서 제거됨) (C++20에서 제거됨) (C++20) |
튜플의 값들을 사전식(lexicographically)으로 비교해요 (함수 템플릿) |
std::swap (std::tuple) (C++11) |
std::swap 알고리즘을 특수화해요 (함수 템플릿) |
헬퍼 개념
tuple-like pair-like (C++23) |
타입이 튜플 프로토콜(std::get, std::tuple_element, std::tuple_size)을 구현했음을 명시해요 (설명 전용 개념*) |
|---|
헬퍼 클래스
std::tuple_size<std::tuple> (C++11) |
튜플의 크기를 구해요 (클래스 템플릿 특수화) |
|---|---|
std::tuple_element<std::tuple> (C++11) |
지정된 요소의 타입을 구해요 (클래스 템플릿 특수화) |
std::uses_allocator<std::tuple> (C++11) |
std::uses_allocator 타입 특성을 특수화해요 (클래스 템플릿 특수화) |
std::basic_common_reference<tuple-like> (C++23) |
튜플과 tuple-like 타입의 공통 참조 타입을 결정해요 (클래스 템플릿 특수화) |
std::common_type<tuple-like> (C++23) |
튜플과 tuple-like 타입의 공통 타입을 결정해요 (클래스 템플릿 특수화) |
std::formatter<std::tuple> (C++23) |
튜플에 대한 서식 지정 지원이에요 (클래스 템플릿 특수화) |
ignore (C++11) |
tie로 튜플을 풀 때 요소를 건너뛰기 위한 자리표시자예요 (상수) |
헬퍼 특수화
template < class ... Ts > constexpr bool enable_nonlocking_formatter_optimization < std :: tuple < Ts ... >> = ( enable_nonlocking_formatter_optimization < Ts > && ...); |
(C++23부터) |
|---|
std::enable_nonlocking_formatter_optimization의 이 특수화는 각 요소 타입이 활성화할 때 튜플 객체를 출력하기 위한 std::print와 std::println의 효율적인 구현을 가능하게 해요.
연역 가이드 (C++17부터)
참고 사항
N4387(C++11에 대한 결함 보고서로 적용됨) 이전에는 함수가 복사 목록 초기화(copy-list-initialization)를 사용해 튜플을 반환할 수 없었어요:
std::tuple<int, int> foo_tuple()
{
return {1, -1}; // Error until N4387
return std::tuple<int, int>{1, -1}; // Always works
return std::make_tuple(1, -1); // Always works
}
예제
#include <iostream>
#include <stdexcept>
#include <string>
#include <tuple>
std::tuple<double, char, std::string> get_student(int id)
{
switch (id)
{
case 0: return {3.8, 'A', "Lisa Simpson"};
case 1: return {2.9, 'C', "Milhouse Van Houten"};
case 2: return {1.7, 'D', "Ralph Wiggum"};
case 3: return {0.6, 'F', "Bart Simpson"};
}
throw std::invalid_argument("id");
}
int main()
{
const auto student0 = get_student(0);
std::cout << "ID: 0, "
<< "GPA: " << std::get<0>(student0) << ", "
<< "grade: " << std::get<1>(student0) << ", "
<< "name: " << std::get<2>(student0) << '\n';
const auto student1 = get_student(1);
std::cout << "ID: 1, "
<< "GPA: " << std::get<double>(student1) << ", "
<< "grade: " << std::get<char>(student1) << ", "
<< "name: " << std::get<std::string>(student1) << '\n';
double gpa2;
char grade2;
std::string name2;
std::tie(gpa2, grade2, name2) = get_student(2);
std::cout << "ID: 2, "
<< "GPA: " << gpa2 << ", "
<< "grade: " << grade2 << ", "
<< "name: " << name2 << '\n';
// C++17 structured binding:
const auto [gpa3, grade3, name3] = get_student(3);
std::cout << "ID: 3, "
<< "GPA: " << gpa3 << ", "
<< "grade: " << grade3 << ", "
<< "name: " << name3 << '\n';
}
출력:
ID: 0, GPA: 3.8, grade: A, name: Lisa Simpson
ID: 1, GPA: 2.9, grade: C, name: Milhouse Van Houten
ID: 2, GPA: 1.7, grade: D, name: Ralph Wiggum
ID: 3, GPA: 0.6, grade: F, name: Bart Simpson
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었어요.
| DR | 적용 대상 | 발표 당시 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2796 | C++11 | std::tuple 소멸자의 trivial 여부가 명시되지 않았음 |
명시됨 |
| LWG 3990 | C++11 | 프로그램이 std::tuple의 명시적 또는 부분 특수화를 선언할 수 있었음 |
이 경우 프로그램은 ill-formed임 (진단 불필요) |
참고 문헌
- C++23 표준 (ISO/IEC 14882:2024): 22.4 Tuples [tuple]
- C++20 표준 (ISO/IEC 14882:2020): 20.5 Tuples [tuple]
- C++17 표준 (ISO/IEC 14882:2017): 23.5 Tuples [tuple]
- C++14 표준 (ISO/IEC 14882:2014): 20.4 Tuples [tuple]
- C++11 표준 (ISO/IEC 14882:2011): 20.4 Tuples [tuple]
같이 보기
pair |
두 값의 쌍, 즉 이진 튜플을 구현해요 (클래스 템플릿) |
|---|