std::tuple<Types...>:: tuple
|
헤더 파일에 정의됨
<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,
|
(16) |
(C++11부터)
(C++20부터 constexpr) (조건부 explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(17) |
(C++11 이후)
(C++20 이후 constexpr) (조건부 explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(18) |
(C++23부터)
(조건부 explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(19) |
(C++11 이후)
(C++20 이후 constexpr) (조건부 explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(20) |
(C++11부터)
(C++20부터 constexpr) (조건부 explicit) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(21) |
(C++23 이후)
(조건부 explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(22) |
(C++23부터)
(조건부 explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(23) |
(C++11부터)
(C++20부터 constexpr) (조건부 explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(24) |
(C++11 이후)
(C++20 이후 constexpr) (조건부 explicit) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(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,
|
(27) |
(C++11부터)
(C++20부터 constexpr) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(28) |
(C++11부터)
(C++20부터 constexpr) |
새로운 튜플을 생성합니다.
다음 설명에서 다음과 같이 가정합니다.
-
i
가 범위
[ 0 ,sizeof... ( Types ))내에서 순서대로 존재하고, -
Ti가Types의i번째 타입이며, -
Ui가UTypes라는 이름의 템플릿 매개변수 팩에서i번째 타입인 경우,
인덱싱은 0부터 시작합니다.
- 이 오버로드는 모든 i 에 대해 std:: is_default_constructible < Ti > :: value 가 true 인 경우에만 오버로드 해결에 참여합니다.
-
생성자는 적어도 하나의
i
에 대해
Ti가 { } 에서 copy-list-initializable하지 않은 경우에만 explicit 입니다.
- 이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다: sizeof... ( Types ) >= 1 그리고 std:: is_copy_constructible < Ti > :: value 가 모든 i 에 대해 true 인 경우.
- 이 생성자는 다음 조건을 만족할 때만 explicit 입니다: std:: is_convertible < const Ti & , Ti > :: value 가 적어도 하나의 i 에 대해 false 인 경우.
-
이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다:
- 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 이어야 합니다.
-
만약
sizeof...
(
Types
)
==
1
이면,
- 이 생성자는 explicit 이며, 다음 조건을 만족할 때만 그렇습니다: std:: is_convertible < Ui, Ti > :: value 가 적어도 하나의 i 에 대해 false 인 경우.
|
(C++23 이후) |
공식적으로,
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 이고,
-
다음 중 하나를 만족할 때:
- sizeof... ( Types ) 가 1 이 아니거나,
-
(
Types...가T로 확장되고UTypes...가U로 확장될 때) std:: is_convertible_v < decltype ( other ) , T > , std:: is_constructible_v < T, decltype ( other ) > , 그리고 std:: is_same_v < T, U > 가 모두 false 인 경우.
- 이 생성자들은 다음 조건일 때만 explicit 입니다: std:: is_convertible_v < decltype ( std :: get < i > ( FWD ( other ) ) ) , Ti > 가 적어도 하나의 i 에 대해 false 인 경우.
|
(C++23부터) |
공식적으로, FWD ( p ) 를 std:: forward < decltype ( p ) > ( p ) 로 정의하고, 첫 번째 요소를 std :: get < 0 > ( FWD ( p ) ) 로, 두 번째 요소를 std :: get < 1 > ( FWD ( p ) ) 로 초기화합니다.
-
이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다:
- sizeof... ( Types ) == 2 ,
- std:: is_constructible_v < T0, decltype ( std :: get < 0 > ( FWD ( p ) ) ) > 가 true 이고,
- std:: is_constructible_v < T1, decltype ( std :: get < 1 > ( FWD ( p ) ) ) > 가 true 인 경우.
- 이 생성자는 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) |
tuple-like
생성자.
u
의 해당 요소로부터 각 요소가 생성된 튜플을 생성합니다.
공식적으로, 모든
i
에 대해, 튜플의
i
번째 요소를
std
::
get
<
i
>
(
std::
forward
<
UTuple
>
(
u
)
)
로 초기화합니다.
-
이 오버로드는 다음 조건을 모두 만족할 때만 오버로드 해결에 참여합니다:
- std:: same_as < std:: remove_cvref_t < UTuple > , std:: tuple > 가 false 인 경우,
- std:: remove_cvref_t < UTuple > 가 std::ranges::subrange 의 특수화가 아닌 경우,
- sizeof... ( Types ) 가 std:: tuple_size_v < std:: remove_cvref_t < UTuple >> 와 같은 경우,
- 모든 i 에 대해 std:: is_constructible_v < Ti, decltype ( std :: get < i > ( std:: forward < UTuple > ( u ) ) ) > 가 true 인 경우, 그리고
-
다음 중 하나인 경우:
- sizeof... ( Types ) 가 1 이 아닌 경우, 또는
-
(
Types...가T로 확장될 때) std:: is_convertible_v < UTuple, T > 와 std:: is_constructible_v < T, UTuple > 가 모두 false 인 경우.
- 참조인 요소의 초기화가 임시 객체에 바인딩되는 경우 이 생성자는 삭제된 것으로 정의됩니다.
- 이 생성자는 수행하는 모든 연산이 constexpr 인 경우 constexpr 입니다. 빈 튜플 std:: tuple <> 의 경우, 이는 constexpr 입니다.
- std:: is_copy_constructible < Ti > :: value 가 모든 i 에 대해 true 여야 하며, 그렇지 않으면 동작이 정의되지 않음 (C++20 이전) 프로그램이 형식 오류 (C++20 이후) .
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 이후) .
목차 |
매개변수
| 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) |
|
(C++11)
|
forwarding references
의
tuple
을 생성합니다
(function template) |
새로운
pair
를 생성합니다
(
std::pair<T1,T2>
의 public member function)
|