네, 본문에서는 그런 게 있다는 것만 언급하고 그것까지 구체적인 예를 들지는 (귀찮아서-_-) 않았습니다.
그렇게 자신 바깥의 context까지 끌어들이는 개념이 있기 때문에 람다 함수는 더욱 함수 포인터와 동등한 개념이 될 수 없고 그걸 초월하여 더 상위에 있는 개념이 되겠죠.
어떤 함수 안에서 또 반복되는 코드 블록을 간추릴 필요가 있을 때 #define의 역할을 잘 대체할 수 있습니다.
#include <functional>
으로 functional 을 인클루드 한 뒤에,
std::function<리턴형(인수1, 인수2, 인수3)>
형식으로 선언하면, 같은 형식의 람다함수를 저장할 수 있습니다.(당연히 using namespace std; 했다면, std:: 는 생략가능)
예를 들어,
std::function<void(int, int, Player&, Player&, int, int)> command;
이런 식으로 정의를 했다면,
command = [](int self, int target, Player& player, Player& foes, int currentAbilityIndex, int turn) { /* ... */ }
는 식으로 대입이 가능합니다.
저는 이런 식으로 클래스 멤버변수로 람다함수를 가지는 코드도 만든 전적이 있습니다. (전략 패턴으로 쓰기 위해서 ㄳ. 특징상 전략 패턴에 쓰기에도 딱 맞더군요)
보충 설명에 감사합니다.
람다가 auto 말고 다른 곳에 대입 가능하다는 건 완전 처음 듣네요...!
리턴형(인수1, 인수2, 인수3) ... 이건 템플릿 인자로만 지정 가능한 타입이고 전적으로 람다를 위해서 C++11에서 새로 추가된 문법인 거겠죠?
C++ 라이브러리도 다 C++ 문법 위에서 만들어진 코드일 테니 저는 언어적인 근간을 더 먼저 따져 보는 걸 좋아합니다.
C++11에 새로 추가된 문법은 아니고 boost에서 개발하여 c++11에 정식으로 추가된 범용 함수객체와 바인더, 플레이스홀더 라이브러리 입니다.
문법이 아니라 템플릿의 타입추론을 이용하여 라이브러리 레벨에서 구현된겁니다.
C++11을 지원하는 컴파일러엔 std::function 으로 사용 가능하고 그 이전의 컴파일러라면 boost 설치 후 boost::function 으로 사용 가능합니다
결국 템플릿 인자와 함수 자체의 인자에 동일한 함수 프로토타입이 두 번 명시되는 꼴이군요.
이걸 안 하고서 m_dat 호출만 하면 코드가 컴파일은 되지만 결국 링크 에러가 납니다.
템플릿 함수라도 타입이 명확하게 지정되어 있는 특화된 몸체는 다른 번역 단위(소스 코드)에 있어도 괜찮습니다.
그에 반해 typename이라는 것만 명시되어 있는 추상적인 몸체는, 사용되는 모든 번역 단위에서 일일이 인클루드되어야 사용 가능합니다.
그것도 외부 번역 단위에서 알아서 끌어다 쓸 수 있게 하려고 제안되었던 기능이 export 키워드인데 완전히 흑역사로 전락했고, C++11에서는 보류 정도가 아니라 삭제되어 버린 것 아시죠?
단순히 변수 타입 정도가 아니라 멤버 함수와 람다까지 왔다갔다 할 수 있는 템플릿은 그 유연함이 가히 #define에 맞먹는 수준인데, 그 모든 가능성을 그것도 기계어 코드 컴파일 언어에서 export 가능하려면 컴파일러와 링커를 다 새로 만들지 않고서는 불가능할 겁니다.
아무리 생각해도 T가 멤버 함수까지 가리킬 수 있는 건 좀 흉악(?)한 것 같습니다.
typename이라는 키워드가 있는 것처럼 funcname 같은 다른 힌트 지정자라도 있는 게 낫지 않을까 싶기도 하군요.
또한, C++ 멤버 함수와 람다 함수는 직접적으로 관계가 있는 게 아닌데 std::function 클래스는 아무리 템플릿이라 해도 어떻게 람다와 곧장 직결이 가능한지 모르겠습니다.
함수 호출 규약이나 기계어 메모리 구조와 관련된 트릭을 쓰기라도 한 건지, 라이브러리 소스를 봐서는 모르겠고요. (온갖 외계어 같은 #define과 typedef 꼼수들.. -_-)
그 기능만을 위한 문법이 따로 존재하는 게 아니라면 어떤 형태로든 꼼수가 안 들어갈 수는 없을 텐데요.
그리고 xcode에서는 MyObject<int(int)>와 같은 문법이 컴파일이 안 되더군요. #include <functional>을 해도 std::function라는 명칭 자체도 없고요. C++11 표준이 일부 반영되어 있음에도 불구하고 그쪽은 지원되지 않는 듯합니다.
그나저나,
1. 본이 아니게 댓글이 무진장 길어졌는데, 이거 조만간 본문으로 옮길 예정.
2. 링크가 걸리는 URL도 있고, 안 걸리는 URL도 경험상 있는데, 정확한 차이는 저도 잘 모르겠습니다.
람다 함수는 뭐 자바스크립트 루비 파이썬 등등 요새 많이 사용되는 언어에는 거의 있죠. 근데 C++에도 들어가게 되다니 이거 참...... 제가 컴파일러 쪽은 잘 모르다보니 어떻게 인터프리터 언어도 아닌 C++에서 어떻게 클로져를 구현한 건지 모르겠네요. 생각 좀 해봐야 되나