본문 바로가기

프로그래밍/C++

C++ 익명함수 사용법

익명함수라고?


익명함수라.. 어디에서 들어보았는가? 아마 자바스크립트나 자바 또는 다른 객체지향 언어에서 들어보았을 것이다. 익명함수는 말그대로 이름이 없는 함수인데, 객체지향에서는 변수에 저장해놓고 사용하거나 특정 행동에 대한 처리를 하기 위해 주로 사용된다.(객체지향의 큰 특징중 하나)


그런데, 이런 익명함수 개념이 객체지향 언어라 그런지, 어쩌다 보니 C++까지 오게 되었다. 그것도 정말 편리한 익명함수의 새로운 표기법인 "람다"를 이끌고 말이다. 그럼, 이런 C++ 익명함수/람다식의 사용법을 자세히 알아보도록 하자.


(JS의 람다를 알아보고 싶다면 여기)


익명함수 사용하기


1
2
3
[]{ 실행내용 }
[](매개변수){ 실행내용 }
[](매개변수)->반환타입{ 실행내용 }
cs


익명함수의 주요 사용법 3가지다. 먼저 첫번째의 경우는 함수를 호출할때 쓰이는 매개변수가 필요하지 않은 경우에 사용할 수 있고(단순 실행), 두번째의 경우에는 보통 생각하는 '함수'를 만들 수 있다. 매개변수가 있고 리턴값이 있는 그런 함수 말이다. 그리고 마지막 세번째는 많이 긴데, 그냥 두번째에서 '반환타입' 만 지정해준 것이다.


여기서 원래는 반환타입이 정확히 지정되어 있어야 되는 C++의 문법에는 알맞지 않느냐 라는 생각이 드는 사람도 있을 것이다. 하지만 이 문법이 '익명함수' 이기도 하지만, 앞에서 말했듯이 람다식 표기법이기에 어쩔 수 없다. 람다는 짧고 편리한 것을 최우선으로 생각하기 때문에 그런것이다.


함수 저장하기


위에서 말했던 방식으로 생성된 함수들은, 변수에 저장하거나 바로 사용하거나 둘 중 하나가 될 것이다.


바로 사용하는 데에는 아무런 문제도 없지만, 바로 사용하지 않고 변수에 담아둘때는 어떻게 해야 될까? 한번 같이 알아보자.


1
2
3
4
5
6
7
8
9
10
11
#include "functional"
 
using namespace std;
 
int main() {
    function<int(intint)> f = [](int a, int b) { return a + b; };
    return 0;
}
cs


함수를 저장하는데에는 "functional" 헤더를 include 해주어야 한다. C++의 주축인 std namespace도 using해줘야 된다. 그렇게 하고 난 뒤에, function 클래스를 이용해서 객체를 생성해주면 된다. (제네릭 사용)


function<반환타입(매개변수)> 변수명 = 익명함수;


이런식으로 써주면 되겠다. 물론, 이 함수들을 호출할때에는 변수명(인수) 로 해주면 된다.



활용 예제


그럼, 이걸 활용한 예제를 보도록 하자.


1
2
3
4
5
6
7
8
9
10
11
#include "functional"
#include "iostream"
 
using namespace std;
 
int main() {
    function<int(intint)> f = [](int a, int b) { return a + b; };
    cout << f(48<< endl;
    system("pause");
    return 0;
}
cs


위 예제에서는 f라는 변수에 두 개의 인수를 받아 더한 값을 반환하는 익명함수를 저장한다. 그런 다음, cout을 이용해 f를 4와 8을 인수로 호출한 반환값을 출력한다. 그리고 멈추게 한 뒤, 프로그램을 종료시킨다.



작동은 잘 된다.


정리


보통 이런 익명함수들은 리스너(특정 행동에 대한 코드 지정)나 비동기적 콜백에서 사용된다. 사실 이게 C++를 하면서 그렇게 잘 쓰일지는 모르겠지만, 객체지향에서의 중요한 문법 중 하나이니 잘 익혀 두도록 하자. 그럼 이번 글은 여기에서 마치도록 하겠다. 끝.

'프로그래밍 > C++' 카테고리의 다른 글

C++ Vector 무한배열 사용법  (0) 2017.11.04