Namespaces
Variants

std::tuple<Types...>:: tuple

From cppreference.net
Utilities library
헤더 파일에 정의됨 <tuple>
constexpr tuple ( ) ;
(1) (C++11부터)
(조건부 explicit)
tuple ( const Types & ... args ) ;
(2) (C++11부터)
(C++14부터 constexpr)
(조건부 explicit)
template < class ... UTypes >
tuple ( UTypes && ... args ) ;
(3) (C++11부터)
(C++14부터 constexpr)
(조건부 explicit)
template < class ... UTypes >
constexpr tuple ( tuple < UTypes... > & other ) ;
(4) (C++23부터)
(조건적으로 explicit)
template < class ... UTypes >
tuple ( const tuple < UTypes... > & other ) ;
(5) (C++11 이후)
(C++14 이후 constexpr)
(조건부 explicit)
template < class ... UTypes >
tuple ( tuple < UTypes... > && other ) ;
(6) (C++11부터)
(C++14부터 constexpr)
(조건부 explicit)
template < class ... UTypes >
constexpr tuple ( const tuple < UTypes... > && other ) ;
(7) (C++23부터)
(조건적으로 explicit)
template < class U1, class U2 >
constexpr tuple ( std:: pair < U1, U2 > & p ) ;
(8) (C++23 이후)
(조건적으로 explicit)
template < class U1, class U2 >
tuple ( const std:: pair < U1, U2 > & p ) ;
(9) (C++11부터)
(C++14부터 constexpr)
(조건부 explicit)
template < class U1, class U2 >
tuple ( std:: pair < U1, U2 > && p ) ;
(10) (C++11 이후)
(C++14 이후 constexpr)
(조건부 explicit)
template < class U1, class U2 >
constexpr tuple ( const std:: pair < U1, U2 > && p ) ;
(11) (C++23 이후)
(조건부 explicit)
template < tuple-like UTuple >
constexpr tuple ( UTuple && u ) ;
(12) (C++23부터)
(조건부 explicit)
tuple ( const tuple & other ) = default ;
(13) (C++11부터)
tuple ( tuple && other ) = default ;
(14) (C++11 이후)
할당자 확장 생성자
template < class Alloc >
tuple ( std:: allocator_arg_t , const Alloc & a ) ;
(15) (C++11부터)
(C++20부터 constexpr)
(조건부 explicit)
template < class Alloc >

tuple ( std:: allocator_arg_t , const Alloc & a,

const Types & ... args ) ;
(16) (C++11부터)
(C++20부터 constexpr)
(조건부 explicit)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

UTypes && ... args ) ;
(17) (C++11 이후)
(C++20 이후 constexpr)
(조건부 explicit)
template < class Alloc, class ... UTypes >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

tuple < UTypes... > & other ) ;
(18) (C++23부터)
(조건부 explicit)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

const tuple < UTypes... > & other ) ;
(19) (C++11 이후)
(C++20 이후 constexpr)
(조건부 explicit)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

tuple < UTypes... > && other ) ;
(20) (C++11부터)
(C++20부터 constexpr)
(조건부 explicit)
template < class Alloc, class ... UTypes >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

const tuple < UTypes... > && other ) ;
(21) (C++23 이후)
(조건부 explicit)
template < class Alloc, class U1, class U2 >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

std:: pair < U1, U2 > & p ) ;
(22) (C++23부터)
(조건부 explicit)
template < class Alloc, class U1, class U2 >

tuple ( std:: allocator_arg_t , const Alloc & a,

const std:: pair < U1, U2 > & p ) ;
(23) (C++11부터)
(C++20부터 constexpr)
(조건부 explicit)
template < class Alloc, class U1, class U2 >

tuple ( std:: allocator_arg_t , const Alloc & a,

std:: pair < U1, U2 > && p ) ;
(24) (C++11 이후)
(C++20 이후 constexpr)
(조건부 explicit)
template < class Alloc, class U1, class U2 >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

const std:: pair < U1, U2 > && p ) ;
(25) (C++23 이후)
(조건부 explicit)
template < class Alloc, tuple - like UTuple >
constexpr tuple ( std:: allocator_arg_t , const Alloc & a, UTuple && u ) ;
(26) (C++23 이후)
(조건부 explicit)
template < class Alloc >

tuple ( std:: allocator_arg_t , const Alloc & a,

const tuple & other ) ;
(27) (C++11부터)
(C++20부터 constexpr)
template < class Alloc >

tuple ( std:: allocator_arg_t , const Alloc & a,

tuple && other ) ;
(28) (C++11부터)
(C++20부터 constexpr)

새로운 튜플을 생성합니다.

다음 설명에서 다음과 같이 가정합니다.

  • i 가 범위 [ 0 , sizeof... ( Types ) ) 내에서 순서대로 존재하고,
  • Ti Types i 번째 타입이며,
  • Ui UTypes 라는 이름의 템플릿 매개변수 팩에서 i 번째 타입인 경우,

인덱싱은 0부터 시작합니다.

1) 기본 생성자. 값 초기화 를 모든 요소에 수행합니다. sizeof... ( Types ) == 0 인 경우 기본 생성자는 trivial입니다.
  • 이 오버로드는 모든 i 에 대해 std:: is_default_constructible < Ti > :: value true 인 경우에만 오버로드 해결에 참여합니다.
  • 생성자는 적어도 하나의 i 에 대해 Ti { } 에서 copy-list-initializable하지 않은 경우에만 explicit 입니다.
2) 직접 생성자. 튜플의 각 요소를 해당 매개변수로 초기화합니다.
  • 이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다: sizeof... ( Types ) >= 1 그리고 std:: is_copy_constructible < Ti > :: value 가 모든 i 에 대해 true 인 경우.
  • 이 생성자는 다음 조건을 만족할 때만 explicit 입니다: std:: is_convertible < const Ti & , Ti > :: value 가 적어도 하나의 i 에 대해 false 인 경우.
3) 변환 생성자. 튜플의 각 요소를 std:: forward < UTypes > ( args ) 의 해당 값으로 초기화합니다.
  • 이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다:
    • sizeof... ( Types ) == sizeof... ( UTypes ) ,
    • sizeof... ( Types ) >= 1 ,
    • std:: is_constructible < Ti, Ui > :: value 가 모든 i 에 대해 true 이고, 그리고
    • D std:: decay < U0 > :: type (C++20 이전) std:: remove_cvref_t < U0 > (C++20 이후) 라고 할 때,
      • 만약 sizeof... ( Types ) == 1 이면, D std::tuple 이 아니어야 하고, 그렇지 않으면
      • 만약 sizeof... ( Types ) == 2 또는 sizeof... ( Types ) == 3 이면, D std::allocator_arg_t 가 아니거나, T0 std::allocator_arg_t 이어야 합니다.
  • 이 생성자는 explicit 이며, 다음 조건을 만족할 때만 그렇습니다: std:: is_convertible < Ui, Ti > :: value 가 적어도 하나의 i 에 대해 false 인 경우.
(C++23 이후)
4-7) 변환 생성자. 튜플의 각 요소를 other 의 해당 요소로 초기화합니다.

공식적으로, FWD ( other ) std:: forward < decltype ( other ) > ( other ) 로 정의할 때, 모든 i 에 대해 튜플의 i 번째 요소를 std :: get < i > ( FWD ( other ) ) 로 초기화합니다.

  • 이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다:
    • sizeof... ( Types ) == sizeof... ( UTypes ) ,
    • std:: is_constructible_v < Ti, decltype ( std :: get < i > ( FWD ( other ) ) ) > 가 모든 i 에 대해 true 이고,
    • 다음 중 하나를 만족할 때:
  • 이 생성자들은 다음 조건일 때만 explicit 입니다: std:: is_convertible_v < decltype ( std :: get < i > ( FWD ( other ) ) ) , Ti > 가 적어도 하나의 i 에 대해 false 인 경우.
  • 참조인 임의의 요소의 초기화가 임시 객체에 바인딩하는 경우 이 생성자들은 삭제된 것으로 정의됩니다.
(C++23부터)
8-11) Pair 생성자. p 의 해당 요소로부터 각 요소를 생성하여 2개 요소 튜플을 구성합니다.

공식적으로, FWD ( p ) std:: forward < decltype ( p ) > ( p ) 로 정의하고, 첫 번째 요소를 std :: get < 0 > ( FWD ( p ) ) 로, 두 번째 요소를 std :: get < 1 > ( FWD ( p ) ) 로 초기화합니다.

  • 이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다:
  • 이 생성자는 explicit 이며, 다음 조건 중 하나라도 만족할 때만 explicit입니다: std:: is_convertible_v < decltype ( std :: get < 0 > ( FWD ( p ) ) ) , T0 > 또는 std:: is_convertible_v < decltype ( std :: get < 1 > ( FWD ( p ) ) ) , T1 > false 인 경우.
  • 참조인 임의의 요소 초기화가 임시 객체에 바인딩될 경우 이 생성자들은 삭제된 것으로 정의됩니다.
(since C++23)
12) tuple-like 생성자. u 의 해당 요소로부터 각 요소가 생성된 튜플을 생성합니다.

공식적으로, 모든 i 에 대해, 튜플의 i 번째 요소를 std :: get < i > ( std:: forward < UTuple > ( u ) ) 로 초기화합니다.

13) 암시적으로 정의된 복사 생성자. 튜플의 각 요소를 other 의 해당 요소로 초기화합니다.
  • 이 생성자는 수행하는 모든 연산이 constexpr 인 경우 constexpr 입니다. 빈 튜플 std:: tuple <> 의 경우, 이는 constexpr 입니다.
  • std:: is_copy_constructible < Ti > :: value 가 모든 i 에 대해 true 여야 하며, 그렇지 않으면 동작이 정의되지 않음 (C++20 이전) 프로그램이 형식 오류 (C++20 이후) .
14) 암시적으로 정의된 이동 생성자. 모든 i 에 대해, 튜플의 i 번째 요소를 std:: forward < Ui > ( std :: get < i > ( other ) ) 로 초기화합니다.
  • 이 생성자는 수행하는 모든 연산이 constexpr 인 경우 constexpr 입니다. 빈 튜플 std:: tuple <> 의 경우, 이는 constexpr 입니다.
  • std:: is_move_constructible < Ti > :: value 가 모든 i 에 대해 true 여야 하며, 그렇지 않으면 동작이 정의되지 않음 (C++20 이전) 이 오버로드는 오버로드 해결에 참여하지 않음 (C++20 이후) .
15-28) (1-14) 와 동일하지만, 각 요소가 uses-allocator construction 을 통해 생성됩니다. 즉, Allocator 객체 a std:: uses_allocator < Ui, Alloc > :: value true 인 각 요소의 생성자에 추가 인수로 전달됩니다.

목차

매개변수

args - 튜플의 각 요소를 초기화하는 데 사용되는 값들
other - 튜플의 각 요소를 초기화하는 데 사용되는 값들의 튜플
p - 2-튜플의 두 요소를 모두 초기화하는 데 사용되는 값들의 쌍
u - 튜플의 각 요소를 초기화하는 데 사용되는 값들의 tuple-like 객체
a - uses-allocator construction에서 사용할 할당자

참고 사항

조건부 명시적 생성자는 복사 초기화 문맥에서 목록 초기화 구문을 사용하여 튜플을 생성할 수 있게 합니다:

std::tuple<int, int> foo_tuple() 
{
    // return {1, -1};             // N4387 이전에는 오류
    return std::make_tuple(1, -1); // 항상 동작함
}

리스트의 일부 요소가 대상 튜플의 해당 요소로 암시적으로 변환되지 않는 경우, 생성자가 명시적(explicit)이 된다는 점에 유의하십시오:

using namespace std::chrono;
void launch_rocket_at(std::tuple<hours, minutes, seconds>);
launch_rocket_at({hours(1), minutes(2), seconds(3)}); // 정상
launch_rocket_at({1, 2, 3}); // 오류: int는 duration으로 암시적으로 변환될 수 없음
launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // 정상

예제

#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <vector>
// 벡터를 스트림에 출력하는 헬퍼 함수
template<class Os, class T>
Os& operator<<(Os& os, std::vector<T> const& v)
{
    os << '{';
    for (auto i{v.size()}; const T& e : v)
        os << e << (--i ? "," : "");
    return os << '}';
}
template<class T>
void print_single(T const& v)
{
    if constexpr (std::is_same_v<T, std::decay_t<std::string>>)
        std::cout << std::quoted(v);
    else if constexpr (std::is_same_v<std::decay_t<T>, char>)
        std::cout << "'" << v << "'";
    else
        std::cout << v;
}
// 임의 크기의 튜플을 출력하는 헬퍼 함수
template<class Tuple, std::size_t N>
struct TuplePrinter
{
    static void print(const Tuple& t)
    {
        TuplePrinter<Tuple, N - 1>::print(t);
        std::cout << ", ";
        print_single(std::get<N - 1>(t));
    }
};
template<class Tuple>
struct TuplePrinter<Tuple, 1>
{
    static void print(const Tuple& t)
    {
        print_single(std::get<0>(t));
    }
};
template<class... Args>
void print(std::string_view message, const std::tuple<Args...>& t)
{
    std::cout << message << " (";
    TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
    std::cout << ")\n";
}
// 헬퍼 함수 종료
int main()
{
    std::tuple<int, std::string, double> t1;
    print("값 초기화됨, t1:", t1);
    std::tuple<int, std::string, double> t2{42, "테스트", -3.14};
    print("값으로 초기화된 t2:", t2);
    std::tuple<char, std::string, int> t3{t2};
    print("암시적으로 변환됨, t3:", t3);
    std::tuple<int, double> t4{std::make_pair
(설명: HTML 태그와 속성은 그대로 유지되었으며, C++ 관련 용어인 `std::make_pair`는 번역되지 않았습니다. 링크 구조와 클래스 속성도 원본 형식을 그대로 보존합니다.)(42, 3.14)};
    print("쌍으로부터 생성됨, t4:", t4);
    // 단일 인자 생성자를 가진 Allocator my_alloc이 주어졌을 때
    // my_alloc(int); my_alloc(1)를 사용하여 벡터에 5개의 int를 할당합니다
    using my_alloc = std::allocator<int>;
    std::vector<int, my_alloc> v{5, 1, my_alloc{/* 1 */}};
    // my_alloc(2)를 사용하여 튜플 내 벡터에 5개의 int를 할당
    std::tuple<int, std::vector<int, my_alloc>, double> t5
        {std::allocator_arg, my_alloc{/* 2 */}, 42, v, -3.14};
    print("할당자로 구성됨, t5:", t5);
}

가능한 출력:

값 초기화, t1: (0, "", 0)
값으로 초기화, t2: (42, "Test", -3.14)
암시적 변환, t3: ('*', "Test", -3)
pair로부터 생성, t4: (42, 3.14)
할당자로 생성, t5: (42, {1,1,1,1,1}, -3.14)

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 2510 C++11 기본 생성자가 암시적이었음 조건부 명시적으로 변경됨
LWG 3121 C++11 1-튜플 생성자가 재귀적으로 제약 조건을 확인할 수 있음;
allocator_arg_t 인수가 모호성을 야기함
생성자를 추가로 제약함
생성자
LWG 3158 C++11 기본 생성자에 해당하는
사용자 할당자 생성자가 암시적이었음
조건부 명시적으로 변경됨
LWG 3211 C++11 tuple<> 의 기본 생성자가
trivial인지 여부가 명시되지 않았음
trivial로 요구함
LWG 4045 C++23 tuple-like 생성자가 잠재적으로 댕글링 참조를 생성할 수 있음 삭제된 것으로 정의됨
N4387 C++11 일부 생성자가 명시적이어서 유용한 동작을 방지함 대부분의 생성자가
조건부 명시적으로 변경됨

참고 항목

tuple 의 내용을 다른 tuple 에 할당합니다
(public member function)
(C++11)
인자 타입들로 정의된 타입의 tuple 객체를 생성합니다
(function template)
(C++11)
lvalue 참조들의 tuple 을 생성하거나 tuple을 개별 객체들로 풀어냅니다
(function template)
forwarding references tuple 을 생성합니다
(function template)
새로운 pair 를 생성합니다
( std::pair<T1,T2> 의 public member function)