C++ pair와 tuple
1. std::pair 개념
이번 시간에는 C++에서 자주 사용되는 pair와 tuple에 대해 알아봅니다.
먼저 두 개의 데이터를 하나로 묶어 관리할 수 있는 std::pair를 살펴보겠습니다.
std::pair는 C++ 표준 라이브러리에서 제공하는 타입으로, <utility> 헤더에 정의되어 있습니다.
구조는 매우 간단합니다.
template<class T1, class T2>
struct pair;
두 개의 서로 다른 타입을 저장할 수 있는 템플릿 구조체입니다.
2. std::pair 사용 방법
예를 들어 정수와 문자열을 하나로 묶어 관리할 수 있습니다.
std::pair<int, std::string> person;
person = {1, "Rocky"};
pair 내부 데이터는 다음과 같이 접근합니다.
- first
- 첫 번째 타입에 접근
- second
- 두 번째 타입에 접근
예:
std::cout << person.first;
std::cout << person.second;
출력:
1
Rocky
이처럼 std::pair를 사용하면 단순한 데이터를 묶기 위해 별도의 구조체를 만들 필요가 없어집니다.
3. 함수 반환값으로 pair 활용
pair는 특히 함수에서 두 개 이상의 값을 반환해야 할 때 많이 사용됩니다.
예를 들어 나눗셈 함수를 생각해 봅시다.
divide(A, B)
함수는 결과값을 반환해야 하지만, B == 0인 경우에는 정상적인 결과를 반환할 수 없습니다.
이때:
- 첫 번째 값 → 계산 결과
- 두 번째 값 → 에러 코드
형태로 반환할 수 있습니다.
예:
std::pair<int, int> divide(int a, int b)
{
if(b == 0)
return {-1, 1};
return {a / b, 0};
}
여기서:
- 첫 번째 값
- 나눗셈 결과
- 두 번째 값
- 에러 상태
를 의미합니다.
실제 프로젝트에서는 두 번째 값을 단순한 int 대신 에러 코드를 표현하는 별도의 enum이나 클래스로 정의하는 것이 더 좋은 방법입니다.
4. std::make_pair 사용
pair를 생성할 때 std::make_pair()를 사용할 수도 있습니다.
예:
auto result = std::make_pair(10, 0);
C++에서는 타입 추론이 가능하기 때문에 직접 타입을 작성하지 않아도 됩니다.
5. std::tuple 개념
pair는 두 개의 값만 저장할 수 있다는 제한이 있습니다.
여러 개의 값을 하나로 묶고 싶다면 std::tuple을 사용할 수 있습니다.
tuple은 pair의 일반화된 형태라고 생각하면 됩니다.
예:
std::tuple<double, char, std::string> student;
하나의 객체 안에:
- double
- char
- string
처럼 여러 타입을 함께 저장할 수 있습니다.
6. tuple 데이터 접근 방법
tuple의 데이터는 std::get<>()을 사용하여 접근합니다.
예:
std::cout << std::get<0>(student);
std::cout << std::get<1>(student);
std::cout << std::get<2>(student);
접근 방식:
- get<0>()
- 첫 번째 값
- get<1>()
- 두 번째 값
- get<2>()
- 세 번째 값
예:
auto student = std::make_tuple(
3.8,
'A',
"Lisa Simpson"
);
출력:
3.8
A
Lisa Simpson
7. tuple 타입 선언 방법 개선
기존 방식에서는 타입을 직접 작성해야 합니다.
std::tuple<double, char, std::string> student;
하지만 C++에서는 타입 추론 기능을 활용할 수 있습니다.
std::make_tuple 사용
auto student = std::make_tuple(
3.8,
'A',
"Lisa Simpson"
);
컴파일러가 자동으로 타입을 추론합니다.
8. C++17 구조적 바인딩(structured binding)
C++17부터는 더 편리한 방법이 추가되었습니다.
바로 구조적 바인딩입니다.
예:
auto [grade, level, name] = student;
이렇게 작성하면 tuple 내부 값을 변수처럼 바로 사용할 수 있습니다.
예:
std::cout << grade;
std::cout << level;
std::cout << name;
출력:
3.8
A
Lisa Simpson
기존처럼:
std::get<0>(student)
std::get<1>(student)
std::get<2>(student)
를 반복해서 작성할 필요가 없습니다.
9. pair, tuple, struct 사용 기준
pair와 tuple은 간단한 데이터 묶음을 표현할 때 매우 유용합니다.
하지만 항상 이것들이 정답은 아닙니다.
struct를 사용하는 것이 좋은 경우
- 데이터 구조가 의미를 가지고 있을 때
- 여러 곳에서 반복적으로 사용할 때
- 변수 이름을 명확하게 표현해야 할 때
예:
struct Student
{
double grade;
char level;
std::string name;
};
이런 경우에는 struct가 더 적합합니다.
pair / tuple이 좋은 경우
- 특정 함수 내부에서만 사용하는 임시 데이터
- 한 번만 사용하는 간단한 반환값
- 별도의 타입 정의가 불필요한 경우
예:
return std::make_pair(value, error);
핵심 정리
- std::pair
- 두 개의 데이터를 묶는 타입
- <utility> 헤더에 정의
- first, second로 접근
- std::tuple
- 세 개 이상의 여러 타입을 묶을 수 있는 타입
- std::get<>으로 접근
- std::make_pair, std::make_tuple
- 타입 추론을 이용해 간단하게 생성 가능
- C++17 구조적 바인딩
- auto [a, b, c] 형태로 tuple 데이터를 쉽게 분리 가능
- 데이터 구조가 명확하고 재사용된다면 struct
- 간단한 임시 데이터 묶음이라면 pair 또는 tuple
상황에 맞게 선택하는 것이 중요합니다.
'Fundamental of CS > : : C++' 카테고리의 다른 글
| ISO C++11 does not allow conversion from string literal to 'char *' (0) | 2024.08.27 |
|---|---|
| [Exceptions] goto (0) | 2024.07.31 |
| [Types] Floating Numbers (0) | 2024.07.31 |
| [Set, Map / Hash] std::unordered_map (0) | 2024.07.31 |
| [Set, Map / Hash] Hash Set과 Custom Class (0) | 2024.07.31 |