[C/C++] 람다, 함수객체(Functor) 그리고 함수 포인터의 차이점

그림자왕국·2020년 8월 4일
1

C++

목록 보기
20/24

함수 포인터

함수 포인터는 함수를 주소값으로 받아 사용할 수 있는 포인터다.

bool(*ptr)(int,int) = 함수명; // ptr은 포인터명이다.
ptr(1,2); // 호출

함수포인터를 통해 간편하게 함수를 특정 함수의 파라미터로 전달할 수 있다.

함수 객체

함수객체는 클래스에서 Operator() 연산자 오버로딩을 통해 구현하는 함수다.

class Funct
void Operator()	{
	cout << "함수객체" << endl;
    }

다음과 같이 객체선언 후 객체 자체를 호출() 하면 함수객체가 호출된다.

Funct func;
func(); // "함수객체"

인수 개수에 따라 Generator(발생자), 단항함수, 이항함수 등으로 불린다.

SimpleSort의 3번째 인수로 dn객체를 넣었는데
dn은 Sort함수안에서 cmp(51,829) 형식으로 실행되어
최종적으로 Down의 operator()가 실행되는 것을 유추할 수 있다.

함수객체가 가지는 장점으로서는 함수포인터는 인라인화가 불가능하지만 함수 객체는 인라인화가 가능하다. 하지만 함수 포인터보다 코드 길이가 길어지는 단점이 있다.



람다 표현식

람다(Lamda) 함수는 위의 수고를 덜어주기 위해 등장했으며 새로운 문법을 통해 사용할 수 있다.
람다 함수의 선언식은 다음과 같다.

람다 함수를 호출할 때는 함수객체나 포인터와 같이 ()를 통해 호출한다.
다음은 람다 함수를 이용한 간단한 크기비교 예제다.

SimpleSort의 3번째 인자로 []람다식을 선언하였고 Sort 함수 내에서 cmp 템플릿을 이용하여 전달된 람다식을 함수 내에서 호출하는 것을 확인할 수 있다.

람다식은 선언과 동시에 바로 호출 할 수 있다.

    auto l3 = [](){return 43;};
    cout << l3() << endl;
    auto l4 = [](){return 44;}();
    cout << l4 << endl;

auto l3는 43이 반환되는 람다식의 선언문을 저장하고 있고 함수 형태로 언제든지 호출 할 수 있다.
반면 auto l4는 이미 호출된 람다식의 반환값을 가지고 있고 l4에는 44의 데이터만 존재한다.

겉으로 봐선 헷갈릴 수 있으니 주의하도록 하자.

람다 형식은 조건부로 인라인화가 가능하다.
auto 형으로 람다식을 받을 땐 인라인화가 가능하지만, 함수 포인터로 전달받을 때는 인라인화가 불가능한데 함수 포인터는 다른 주소를 참조할 수 있어서 컴파일러가 어떤 함수가 실행될 지 예측하기 어렵기 때문이다.

profile
언리얼 엔진 매니아입니다.

0개의 댓글