std::tuple<Types...>::tuple
cppreference.net에서
| 헤더 <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) |
새로운 tuple을 생성한다.
다음 설명에서,
i는[0,sizeof...(Types))범위에 있고 순서대로 있으며,Ti는i번째 타입이고,Types는, 그리고Ui는i번째 타입이며, 템플릿 매개변수 팩UTypes에 있고,
여기서 인덱싱은 0부터 시작한다.
1) 기본 생성자. 값 초기화한다 (요소가 있는 경우).
sizeof...(Types) == 0이면 기본 생성자는 사소하다.
- 이 오버로드는 모든
std::is_default_constructible<Ti>::value에 대해true이i일 때만 오버로드 해결에 참여한다. - 생성자는 적어도 하나의
explicit에 대해Ti가{}에서 복사-목록 초기화 가능하지 않은 경우에만i이다.
2) 직접 생성자. tuple의 각 요소를 해당 매개변수로 초기화한다.
- 이 오버로드는
sizeof...(Types) >= 1이고 모든std::is_copy_constructible<Ti>::value에 대해true이i일 때만 오버로드 해결에 참여한다. - 이 생성자는 적어도 하나의
explicit에 대해std::is_convertible<const Ti&, Ti>::value이false인 경우에만i이다.
3) 변환 생성자. tuple의 각 요소를
std::forward<UTypes>(args)의 해당 값으로 초기화한다.
- 이 오버로드는 다음 조건이 모두 충족될 때만 오버로드 해결에 참여한다:
sizeof...(Types) == sizeof...(UTypes),sizeof...(Types) >= 1,std::is_constructible<Ti, Ui>::value모든true에 대해i가- 이고,
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이false인 경우에만i이다.
|
(C++23 이후) |
4-7) 변환 생성자. tuple의 각 요소를
other의 해당 요소로 초기화한다.
공식적으로, FWD(other)을 std::forward<decltype(other)>(other)라 하고, 모든 i에 대해 tuple의 i번째 요소를 std::get<i>(FWD(other))로 초기화한다.
- 이 오버로드는 다음 조건이 모두 충족될 때만 오버로드 해결에 참여한다:
sizeof...(Types) == sizeof...(UTypes),std::is_constructible_v<Ti, decltype(std::get<i>(FWD(other)))>모든true에 대해i이- 이고,
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>이false인 경우에만i이다.
|
(C++23 이후) |
8-11) 쌍 생성자. 각 요소를
p의 해당 요소로부터 생성하여 2-요소 tuple을 생성한다.
공식적으로, 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또는std::is_convertible_v<decltype(std::get<0>(FWD(p))), T0>이std::is_convertible_v<decltype(std::get<1>(FWD(p))), T1>인 경우에만false이다.
|
(C++23 이후) |
12)
tuple-like 생성자. 각 요소를 u의 해당 요소로부터 생성하여 tuple을 생성한다.
공식적으로, 모든 i에 대해 tuple의 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>>와 같고,std::is_constructible_v<Ti, decltype(std::get<i>(std::forward<UTuple>(u)))>모든true에 대해i이- 이고,
sizeof...(Types)이1이 아니거나,- (
Types...이T로 확장될 때)std::is_convertible_v<UTuple, T>와std::is_constructible_v<T, UTuple>가 모두false이다.
- 참조인 요소의 초기화가 임시 객체에 바인딩되는 경우 이 생성자는 삭제된 것으로 정의된다.
13) 암시적으로 정의된 복사 생성자. tuple의 각 요소를
other의 해당 요소로 초기화한다.
- 이 생성자는 수행하는 모든 연산이 constexpr이면 constexpr이다. 빈 tuple
std::tuple<>의 경우 constexpr이다. std::is_copy_constructible<Ti>::value는 모든true에 대해i이어야 하며, 그렇지 않으면 동작이 정의되지 않음(C++20까지)프로그램이 비정형(ill-formed)(C++20부터)이다.
14) 암시적으로 정의된 이동 생성자. 모든
i에 대해 tuple의 i번째 요소를 std::forward<Ui>(std::get<i>(other))로 초기화한다.
- 이 생성자는 수행하는 모든 연산이 constexpr이면 constexpr이다. 빈 tuple
std::tuple<>의 경우 constexpr이다. std::is_move_constructible<Ti>::value는 모든true에 대해i이어야 하며, 그렇지 않으면 동작이 정의되지 않음(C++20까지)이 오버로드는 오버로드 해결에 참여하지 않음(C++20부터)이다.
15-28) (1-14)와 동일하지만, 각 요소가 uses-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) |
|
(C++11)
|
forwarding references
의
tuple
을 생성합니다
(function template) |
새로운
pair
를 생성합니다
(
std::pair<T1,T2>
의 public member function)
|