C++ 아이콘 제작자: Darius Dan - Flaticon
함수는 아니지만 함수 처럼 작동하는 객체 Function Object => Functor
함수 처럼 작동하는 객체 ==> 객체를 함수처럼 작동하게 만든다.
- 이를 위해 operator() 연산자를 오버로딩해야한다 ==> 호출 연산자
함수 객체를 호출하면 객체.operator()(인자값) 형태로 호출하지만 중간에 .operator가 생략
==> 이를 암묵적 호출이라 한다. 반면 위처럼 표현을 온전히 하는것은 명시적 호출이다.
또한 암묵적 호출중 객체를 생성하지 않고 클래스()(인자값) 를 호출해 임시 객체를 통한 암묵적 호출도 있다
왜 사용하나?
장점1. 일반 함수와 달리 호출 연산자 이외 데이터를 저장할 변수를 만들어 필요한 속성, 상태를 포함할 수 있다.
장점2. 함수객체의 생성과 실행 시점이 다르다일반 함수는 호출시 바로 실행되지만 함수 객체는 생겅한다고 실행되는게 아니다.
==> 함수 객체를 함수에 전달해서 사용이 가능하다.
가령 나만의 컨테이너를 만들고 정렬 함수를 만들었다 치자.
그런데 자연스럽게 오름차 순으로 함수를 만들었고 후에 내림차 순의 함수까지 만들고자 할 때
기존의 함수에서 함수를 받는 인자를 추가한다
받은 함수에서 원소 끼리 비교를 수행하여 크면 1 작으면 0 결과값을 반환하고
이에 맞게 정렬을 한다.
template <class T>
T Add(T a, T b) {
return a + b;
}
int main() {
std::cout << Add(1, 2);
}
int add<int>(int a, int b){
return a+b;
}
template <typename A, typename B, typename C>
class test {}; ==> A가 int형이고 C가 double형일 때 다른 방식으로 처리하고 싶다!!
template <typename B>
class test<int, B, double> {};
만약 템플릿 인자가 없더라도 특수화를 하고 싶으면 template<>빈칸 이라도 남겨줘야한다
- 자신 만의 클래스 같은 경우는 비교 연산자가 정의되어 있지 않아 정의가 필요한데
모든 클래스에 비교 연산자를 만들 수 없으니 비교하는 함수를 만들어 템플릿 함수에 전달.- 하지만 위에서 말한 비교 함수에 템플릿 함수를 호출할 때 마다 타입을 전달해야 한다. => 귀찮다.
- 이것을 아래 예시 처럼 디폴트 인자를 사용해 간단하게 사용이 가능
template <typename T, typename Comp = Compare<T>>
T Min(T a, T b){ ... }
Min(a, b) ==> main함수에서 사용함 //원래라면 Min<int, Compare<int>>(a, b)
임의의 개수의 인자를 받는 함수를 만들 수 있다.
template (typename arg, typename... args)
return_type function_name(arg var1, args... var2)
template <typename T, typename... Types>
void print(T arg, Types... args) {
std::cout << arg << ", ";
print(args...);
}
... 으로 표시한 것이 parameter pack이라고 한다.
템플릿 파라미터 팩, 함수 파라미터 팩
==> 0개 이상의 템플릿 인자와 0개 이상의 함수 인자를 표현
위 print 템플릿 함수 예시로 printf(1, 2.2, "3"); 을 호출하면
인자가 여러개여서 가변 길이 템플릿 함수가 호출되고, T에는 첫 번째 매개변수인 1의 int타입 추론되고 arg는 1이 된다.
그리고 나머지는 args가 된다.
그후 재귀적으로 다시 함수가 호출되면서 args값이 전달된다.
만약 인자가 1개이면 c++규칙상 파라미터 팩이 없는 함수의 우선순위가 더 높아서 평범한 함수가 호출된다.
1개의 변수를 만들고 sizeof...() 그 변수를 전달하면 넘겨 받은 파라미터 인자들의 모든 갯수를 리턴.
template <typename... Ints>
int sum_all(Ints... nums) {
return (... + nums);
}
==> return (... + nums); 이것이 Fold형식으로 컴파일은 return ((((1 + 4) + 2) + 3) + 10);으로 해석한다.E는 파라미터 펙에 전달된 인자
1) Fold (E1 op (... op (EN−1 op EN )))
2) Fold (((E1 op E2) op ...) op EN )
3) Fold (E1 op (... op (EN−1 op (EN op init))))
4) Fold ((((init op E1) op E2) op ...) op EN
개인 공부 기록용 블로그입니다.
틀린 부분 있으다면 지적해주시면 감사하겠습니다!!