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>::valuetrue라면, 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::printstd::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 두 값의 쌍, 즉 이진 튜플을 구현해요 (클래스 템플릿)

더 알아보기 (Learn more)

cppreference