Boost에 존재하던 tuple이 C++ 표준으로 채택되었습니다.
C++ TR1부터 사용이 가능해졌지만 C++11에 분류한 것은 이전에 작성한 가변인자 템플릿때문입니다.
tuple은 기존의 std::pair를 확장한 자료형입니다.
std::pair가 2개의 값을 한 번에 저장할 수 있지만 tuple은 제한이 없습니다.
기존의 C++ TR1에서는 10개까지 저장이 되었습니다.
tuple은 2개 이상의 값을 한 번에 반환하거나 전달할 때 사용하면 유용합니다.
물론 구조체를 통해서 가능한 방법이긴 하지만 구조체는 정의를 해서 사용해야 합니다.
tuple을 이용하면 간단하게 다양한 값들을 한 번에 전달이 가능하게 됩니다.
예제 코드는 다음과 같습니다.
#include <tuple>
#include <string>
#include <iostream>
int main()
{
// make tuple variable.
typedef std::tuple<int, std::string, bool> OddOrEven;
OddOrEven myNumber = std::make_tuple(10, std::string("Even"), true);
// get tuple size
std::cout << "size : " << std::tuple_size<decltype(myNumber)>::value << std::endl;
// get each value and get type using std::tuple_element, auto keyword.
std::tuple_element<0, decltype(myNumber)>::type nNum = std::get<0>(myNumber);
auto szVal = std::get<1>(myNumber);
bool bEven = std::get<2>(myNumber);
std::cout << nNum << ", " << szVal << ", " << std::boolalpha << bEven << std::endl;
return 0;
}
먼저, std::tuple<> 안의 <> 안에 필요한 변수 타입들을 작성합니다.
typedef로 해당 타입을 OddOrEven 타입이라고 명명했습니다.
tuple 변수에 값을 넣을 때는 std::make_tuple()을 사용하면 됩니다.
해당하는 위치에 해당하는 값을 넣으면 생성이 됩니다.
tuple 안에 몇 개의 변수가 존재하는지는 std::tuple_size<decltype(myNumber)>::value로 가능합니다.
decltype(myNumber)는 C++11에서 생긴 문법으로 해당 변수의 타입을 유추해줍니다.
간단하게 auto와 비슷한 기능이라고 할 수 있습니다.
값을 가져올 때는 std::get<n>(myNumber)로 가져올 수 있습니다.
인덱스는 0부터 시작해서 해당하는 위치의 값을 가져옵니다.
std::tuple_element를 사용해서 tuple의 특정 위치의 타입을 가져올 수 있습니다.
또한 auto 키워드, 혹은 직접 타입을 명시하는 것도 가능합니다.
결과는 다음과 같이 출력됩니다.
값들이 정상적으로 출력되는 것을 확인할 수 있습니다.
그 외에 tuple에서 사용되는 함수들입니다.
#include <tuple>
#include <string>
#include <iostream>
void print(std::tuple<int, bool> tVal)
{
std::cout << std::get<0>(tVal) << ", " << std::get<1>(tVal) << std::endl;
}
int main()
{
// make tuple variable.
typedef std::tuple<int, std::string, bool> OddOrEven;
OddOrEven myNumber1 = std::make_tuple(10, std::string("Even"), true);
OddOrEven myNumber2 = std::make_tuple(7, std::string("Odd"), false);
// std::tie() and std::ignore.
int nVal;
bool bEven;
std::tie(nVal, std::ignore, bEven) = myNumber1;
std::cout << nVal << ", " << bEven << std::endl;
// tuple_cat function.
auto myNums = std::tuple_cat(myNumber1, myNumber2);
std::cout << "Value 1 : " << std::get<0>(myNums) << ", " << std::get<1>(myNums) << ", " << std::get<2>(myNums) << std::endl;
std::cout << "Value 2 : " << std::get<3>(myNums) << ", " << std::get<4>(myNums) << ", " << std::get<5>(myNums) << std::endl;
// foward_as_tuple
print(std::forward_as_tuple(nVal, bEven));
return 0;
}
std::tie는 개별 변수들을 tuple처럼 만들어서 tuple의 각 위치의 값을 가져옵니다.
std::ignore를 사용하면 해당 위치는 값을 가져오지 않게 됩니다.
그 외에 std::tuple_cat은 서로 다른 두 타입의 tuple을 한 개로 연결해서 생성하는 역할을 합니다.
그리고 tuple 타입을 받는 함수에 변수를 생성하지 않고 전달할 수 있는 std::forward_as_tuple도 존재합니다.
tuple은 구조체를 정의하지 않고도 값의 조합을 생성할 수 있기 때문에 유용하게 활용이 가능합니다.
'Programming > CPP11&14' 카테고리의 다른 글
[C++11] thread 지원 (1) (0) | 2015.06.27 |
---|---|
[C++11] 새로워진 random number 생성 (0) | 2015.05.22 |
[C++11] 가변인자 템플릿을 위한 sizeof... 연산자 (0) | 2015.03.06 |
[C++11] 가변인자 템플릿(Variadic Templates) (0) | 2015.03.05 |
[C++11] static_assert를 통한 컴파일 타임 검증 (0) | 2015.02.06 |