Variadic Template
Variadic function templates in C++ - GeeksforGeeks
가변 길이 템플릿 (Variadic template)은 여러개의 인자를 가질 수 있습니다.
예를 들어 가변 길이 템플릿을 이용하여 정의한 함수 템플릿은 정해진 숫자가 아닌 가변 길이 인자를 받을 수 있습니다.
Syntax for a variadic function template
아래 코드에서 typename 뒤에 선언된 "..."이 템플릿 파라미터 팩 (parameter pack)입니다.
이 템플릿 파라미터 팩을 선언하면 이 템플릿은 0개 이상의 (가변된 길이의) 인자를 받을 수 있다는 뜻입니다.
template (typename arg, typename... args)
return_type function)name(arg var1, args... var2)
Sample code
아래 소스 코드는 가변 길이 템플릿을 이용하여 여러 개의 인자를 전달받아 화면에 출력하는 예시입니다.
화면에 출력하기 위해 void print( ) 함수를 정의하였는데, 가변 길이 템플릿에서 print ( ) 함수를 호출하기 때문에 void print( ) 함수를 variadic template 아래에 구현하면 컴파일 에러가 발생합니다. 컴파일러는 해당 소스 코드의 앞에 정의 되어 있는 함수밖에 읽지 못하기 때문입니다.
또, c++11에 도입된 가변 길이 템플릿은 한 가지 단점이 있습니다. 재귀 함수 형태로 구성해야 하기 때문에 반드시 재귀 종료 함수 (base case)를 따로 만들어야 한다는 점입니다.
하지만 c++17에 도입된 fold 형식을 사용한다면 훨씬 간단하게 표현할 수 있습니다. 📢 Fold Expression
// C++ program to demonstrate working of Variadic function template
#include <iostream>
using namespace std;
// To handle base case of below recursive
// Variadic function Template
void print() {
cout << "I am empty function and I am called at last. " << endl;
}
// Variadic function template that thakes variable number of argumnets and prints all of them
template <typename T, typename... Types>
void print(T var1, Tpes... var2) {
cout << var << endl;
print(var2...);
}
// Driver code
int main() {
Pirnt(1, 2, 3.14, "Pass me any number of arguments", "I will print");
}
Explanation
아래 구문은 다음의 순서로 해석됩니다.
print(1, 2, 3.1, "Pass me any number of argymnets", "I will print");
첫 번째로 컴파일러는 구문을 다음과 같이 변환합니다. var1에는 1이 전달되고, var2 에는 2, 3.14, ... 이 전달되기 때문입니다.
cout << 1 << endl;
print(2, 3.14, "Pass me any number of arguments", "I will print");
위 과정을 반복하면 인자가 없는 empty 함수를 호출하게 됩니다.
// cout << 1 << endl;
// cout << 2 << endl;
// cout << 3.14 << endl;
// cout << "Pass me any number of arguments" << endl;
// cout << I will print" << endl;
print();
sizeof...
sizeof 연산자는 인자의 크기를 반환하지만, 파라미터 팩으로 전달받은 인자에 sizeof... 연산자를 사용하면 전체 인자의 개수를 반환합니다.
#include <iostream>
// 재귀 호출 종료를 위한 베이스 케이스
int sum_all() { return 0; }
template <typename... Ints>
int sum_all(int num, Ints... nums) {
return num + sum_all(nums...);
}
template <typename... Ints>
double average(Ints... nums) {
return static_cast<double>(sum_all(nums...)) / sizeof...(nums);
}
int main() {
// (1 + 4 + 2 + 3 + 10) / 5
std::cout << average(1, 4, 2, 3, 10) << std::endl;
}
'💻 programming > c++' 카테고리의 다른 글
[c++] mutex, lock guard, unique lock, shared mutex, recursive mutex (0) | 2020.12.16 |
---|---|
[c++] template meta programming (0) | 2020.12.15 |
[c++] functor (function object) (0) | 2020.12.15 |
[c++] template specialization (0) | 2020.12.15 |
[c++] template (0) | 2020.12.15 |
댓글