C++의 std::tuple 클래스 및 해당 멤버 함수
이 기사에서는 C++에서std::tuple
클래스와 해당 멤버 함수를 사용하는 여러 방법을 보여줍니다.
std::make_tuple
함수를 사용하여 C++에서std::tuple
객체 생성
std::tuple
함수는 고정 된 크기의 이기종 유형 컬렉션을 구현하는 STL 클래스 템플릿입니다. 일반적으로 튜플은 유한 요소 시퀀스를 나타 내기 위해 수학에서 자주 사용되지만 프로그래밍 언어에서 다른 유형의 제품과도 관련이 있습니다.
C++에는 2 개의 이기종 객체 만 저장할 수있는std::pair
라는 유사한 클래스가 있습니다. std::tuple
객체 선언은 일반적으로 튜플이 구성되는 유형과 액세스 순서를 지정합니다. 이러한 유형은std::pair
와 유사한 템플릿 매개 변수로 지정됩니다. std::tuple
명령은 다른 생성자로 초기화 할 수 있습니다. 그래도이 경우std::make_tuple
함수를 사용합니다. std::make_tuple
프로세스는 가변 개수의 인수를 취하고 유형을 자동으로 추론합니다. 이 함수는 주어진 값을 포함하는std::tuple
객체를 반환합니다.
다음 예제 프로그램에서 세 값의 튜플을 인쇄하는printTupleOfThree
라는 함수를 구현합니다. 이 템플릿 함수는 요소 수가 다른 튜플을 인쇄 할 수 없습니다. printTupleOfThree
명령은 세 개 이상의 요소가있는 튜플에서 호출 할 수 있지만 처음 세 개만 출력합니다. 따라서 크기가 다른 튜플에 대해 오버로드 된 함수를 정의하는 것은 비효율적이므로 다른 접근 방식을 사용하여 문제를 해결해야합니다.
#include <iostream>
#include <tuple>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::tuple;
using std::vector;
template <typename Tuple>
void printTupleOfThree(Tuple t) {
cout << "(" << std::get<0>(t) << ", " << std::get<1>(t) << ", "
<< std::get<2>(t) << ")" << endl;
}
int main() {
std::vector<string> v1{"one", "two", "three", "four", "five", "six"};
std::vector<int> v2 = {1, 2, 3, 4, 5, 6};
std::vector<float> v3 = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6};
auto t1 = std::make_tuple(v1[0], v1[1], v2[0]);
auto t2 = std::make_tuple(v1[0], v1[1], v2[0], v3[0], v3[1]);
printTupleOfThree(t1);
printTupleOfThree(t2);
return EXIT_SUCCESS;
}
출력:
(one, two, 1)
(one, two, 2)
함수 템플릿을 사용하여 C++에서 모든 크기의 튜플 인쇄
이전 섹션에서 제기 된 문제에 대한 해결책을 가변 템플릿이라고합니다. 후자는 가변 개수의 인수를 받아들이는 템플릿의 기능입니다. printTuple
은TuplePrinter
클래스의print
멤버 함수를 호출하는 가변 템플릿 함수입니다. 후자는print
라는 단일 멤버 함수를 정의하는 클래스 템플릿이지만TuplePrinter
클래스에는 두 가지 정의가 있습니다. 이 구현을 재귀 템플릿 인스턴스화라고하며 템플릿 기반 메타 프로그래밍에서 알려진 기술입니다.
메타 프로그래밍은 컴파일 타임 다형성을 활용하는 방법을 포함하며이 기사가 다룰 수있는 것보다 훨씬 더 큰 주제입니다. 템플릿 기능과이를 사용하는 메타 프로그래밍 기법에 대한 자세한 개요는 C++ 템플릿-The Complete Guide라는 책을 참조하는 것이 가장 좋습니다. 그 결과printTuple
함수가 다른 크기의 튜플 객체와 호환되도록하고 모든 멤버를cout
스트림에 인쇄 할 수 있습니다.
#include <iostream>
#include <tuple>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::tuple;
using std::vector;
template <class Tuple, std::size_t N>
struct TuplePrinter {
static void print(const Tuple& t) {
TuplePrinter<Tuple, N - 1>::print(t);
std::cout << ", " << std::get<N - 1>(t);
}
};
template <class Tuple>
struct TuplePrinter<Tuple, 1> {
static void print(const Tuple& t) { std::cout << std::get<0>(t); }
};
template <class... Args>
void printTuple(const std::tuple<Args...>& t) {
std::cout << "(";
TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
std::cout << ")" << endl;
}
int main() {
std::vector<string> v1{"one", "two", "three", "four", "five", "six"};
std::vector<int> v2 = {1, 2, 3, 4, 5, 6};
std::vector<float> v3 = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6};
auto t1 = std::make_tuple(v1[0], v1[1], v3[0]);
auto t2 = std::make_tuple(v1[0], v1[1], v2[1], v3[0], v3[1]);
printTuple(t1);
printTuple(t2);
return EXIT_SUCCESS;
}
출력:
(one, two, 1.1)
(one, two, 2, 1.1, 2.2)
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook