🔖 INDEX
std::tuple
튜플(std::tuple)은 C++11에서 도입된 컨테이너 유형으로, 서로 다른 타입의 여러 원소를 하나의 단위로 묶을 수 있습니다. 이는 함수에서 여러 값을 반환하거나, 여러 값을 단일 객체로 묶어 전달할 때 유용합니다.
주요 특징
- 다양한 타입의 값: 튜플은 서로 다른 타입의 여러 원소를 저장할 수 있습니다.
- 고정 크기: 튜플의 크기는 생성 시에 결정되며, 나중에 변경할 수 없습니다.
- 값 접근: std::get<index>(tuple) 함수나 구조화된 바인딩을 사용하여 튜플의 원소에 접근할 수 있습니다.
사용 예제
튜플 생성 및 값 할당
#include <tuple>
int main() {
std::tuple<int, double, std::string> t1(1, 3.14, "Hello");
auto t2 = std::make_tuple(2, 2.71, "World");
}
값 접근
int value = std::get<0>(t1); // 1을 반환
std::string str = std::get<2>(t1); // "Hello"를 반환
여러 값 반환
std::tuple<int, double> func() {
return std::make_tuple(1, 3.14);
}
int main() {
auto [val, pi] = func(); // C++17의 구조화된 바인딩을 사용
}
튜플 비교
튜플은 기본적인 비교 연산을 지원합니다. 첫 번째 원소부터 순서대로 비교됩니다.
if (t1 < t2) { /* ... */ }
주요 함수
- std::make_tuple(...): 값들을 받아 튜플을 생성합니다.
- std::get<index>(tuple): 지정된 인덱스의 원소에 접근합니다.
- std::tie(...): 튜플의 원소들을 변수에 바인딩합니다.
주요 이점
- 타입 유연성: 튜플을 사용하면 다양한 데이터 타입을 하나의 컨테이너에 저장할 수 있습니다. 이는 서로 다른 타입의 정보를 묶어 관리하고 전달할 때 유용합니다.
- 복수 반환 값: 여러 값을 한 번에 반환할 필요가 있을 때, 튜플은 이를 간결하게 해결할 수 있습니다. 예를 들어, 함수에서 두 개 이상의 결과 값을 반환하고 싶을 때 튜플을 활용할 수 있습니다.
- 구조화된 바인딩: C++17부터, 튜플의 값을 여러 변수에 한 번에 분배할 수 있는 구조화된 바인딩을 사용할 수 있습니다. 이를 통해 코드의 가독성과 편의성이 크게 향상됩니다.
- 표준 라이브러리와의 통합: std::tuple은 C++ 표준 라이브러리의 일부로 제공되므로, 다른 표준 라이브러리 기능과 잘 통합됩니다. 예를 들어, std::pair와 유사하게 사용되거나, 알고리즘에 유용하게 사용될 수 있습니다.
- 비교 연산: 튜플은 기본적인 비교 연산을 지원합니다. 첫 번째 원소부터 순서대로 비교되므로, 원소 간의 상대적 순서를 기반으로 튜플 전체를 쉽게 비교할 수 있습니다.
- 런타임에 크기나 타입 변경 불가: 튜플의 크기나 타입은 컴파일 시간에 결정되므로, 예기치 않은 변경이나 오류를 방지할 수 있습니다.
- 메모리 효율: 튜플은 메모리 할당 없이 연속적인 메모리 공간에 값을 저장하기 때문에, 동적 메모리 할당의 오버헤드나 프래그먼테이션 문제 없이 효율적으로 메모리를 사용합니다.
Variadic Templates
C++11에서 도입된 가변 인자 템플릿(Variadic Templates)은 함수나 클래스가 가변 수의 템플릿 인자를 받아들일 수 있게 해주는 기능입니다. 이를 사용하여 다양한 타입의 인자들을 처리하는 템플릿 함수나 클래스를 작성할 수 있습니다.
기본 구문
'...' (ellipsis)를 사용하여 가변 인자 템플릿을 선언합니다.
template<typename... Args>
void functionName(Args... args);
사용 예제
가변 인자를 받는 함수 정의
template<typename... Args>
void printValues(Args... args) {
// ...
}
Parameter Pack
가변 인자는 'parameter pack'이라는 형태로 취급됩니다. args...와 같이 ellipsis를 사용하여 parameter pack의 내용을 처리할 수 있습니다.
template<typename T>
void printSingleValue(T value) {
std::cout << value << " ";
}
template<typename... Args>
void printValues(Args... args) {
(printSingleValue(args), ...); // C++17 fold expression
}
int main() {
printValues(1, 2.0, "Hello", 'A');
}
위 예제에서 printValues 함수는 다양한 타입과 수의 인자를 받아들일 수 있습니다. C++17의 fold expression을 사용하여 모든 인자에 대해 printSingleValue 함수를 호출합니다.
클래스 템플릿에서의 활용
가변 인자 템플릿은 클래스 템플릿에서도 사용할 수 있습니다. 예를 들어, std::tuple은 가변 인자 템플릿을 활용한 대표적인 클래스입니다.
주의 사항
- 가변 인자 템플릿은 다루기 까다롭기 때문에 사용 시 주의가 필요합니다. 특히 재귀적 템플릿 패턴을 사용하여 parameter pack을 처리할 때는 종료 조건을 잘 설정해야 합니다.
- C++17의 fold expression을 활용하면 가변 인자 템플릿의 처리가 훨씬 간결하고 직관적이게 됩니다.
std::bind와 std::function
C++11에서는 함수와 관련된 다양한 객체를 쉽게 다룰 수 있게 도와주는 유틸리티와 클래스를 도입하였습니다. 그 중 std::bind와 std::function은 함수 호출을 더 유연하고 일반적인 방식으로 다룰 수 있게 도와줍니다.
std::bind
std::bind는 함수나 함수 객체, 멤버 함수 포인터 등을 받아 고정된 인자나 조건을 적용한 새로운 호출 가능한 객체를 반환합니다.
기본 구문
auto bound_function = std::bind(function_name, arg1, arg2, ...);
사용 예제
#include <iostream>
#include <functional>
void printSum(int a, int b) {
std::cout << a + b << std::endl;
}
int main() {
auto boundPrintSum = std::bind(printSum, 5, 10);
boundPrintSum(); // 출력: 15
}
std::bind에는 _1, _2, ... 등의 placeholder도 사용할 수 있어, 바인딩시에 아직 정해지지 않은 인자를 전달받을 수 있습니다.
auto boundPrintWithPlaceholder = std::bind(printSum, 5, std::placeholders::_1);
boundPrintWithPlaceholder(10); // 출력: 15
std::function
std::function은 호출 가능한 객체를 보관하고 호출하는 일반적인 인터페이스를 제공하는 템플릿 클래스입니다. 함수 포인터, 람다, 멤버 함수 포인터, std::bind로 생성된 객체 등 여러 형태의 호출 가능한 객체를 보관할 수 있습니다.
기본 구문
std::function<return_type(arg_types...)> functionName;
사용 예제
#include <iostream>
#include <functional>
void sayHello() {
std::cout << "Hello!" << std::endl;
}
int main() {
std::function<void()> func = sayHello;
func(); // 출력: Hello!
// 람다 함수와 함께 사용
func = []() { std::cout << "Hello from lambda!" << std::endl; };
func(); // 출력: Hello from lambda!
}
요약
- std::bind: 다양한 함수나 호출 가능한 객체에 대해 인자를 고정하거나 재배치하여 새로운 호출 가능한 객체를 생성합니다.
- std::function: 다양한 형태의 호출 가능한 객체를 일반적인 방식으로 보관하고 호출할 수 있게 도와주는 템플릿 클래스입니다.
'프로그래밍 > C++' 카테고리의 다른 글
C++ Structured Exception Handling (구조화된 예외 처리) (0) | 2023.10.03 |
---|---|
C++11 주요 업데이트 : Deleted Functions, User-defined Literals, constexpr (0) | 2023.10.03 |
C++11 주요 업데이트 : std::regex, Type Traits, Uniform Initialization (0) | 2023.10.03 |
C++11 주요 업데이트 : std::forward_list, std::unordered_map, std::unordered_set (0) | 2023.10.03 |
C++11 주요 업데이트 : override, final, std::thread, std::array (0) | 2023.09.30 |
댓글