C++에서 클래스 함수를 간접적으로 호출할 수 있는 방식 중 mem_fn, bind, bind_front를 아래 예제로 살펴보도록 하겠습니다.
#include <iostream>
#include <functional>
using namespace std;
class test_class_fn
{
public:
int add(int a, int b)
{
return a + b;
}
auto get_func_mem_fn()
{
return mem_fn(&test_class_fn::add);
}
function<int(int, int)> get_func_bind()
{
return bind(&test_class_fn::add, this, std::placeholders::_1, std::placeholders::_2);
}
function<int(int, int)> get_func_bind_front()
{
return bind_front(&test_class_fn::add, this);
}
};
int main(int argc, char* argv[])
{
test_class_fn test;
auto func0 = test.get_func_mem_fn();
function<int(int, int)> func1 = test.get_func_bind();
function<int(int, int)> func2 = test.get_func_bind_front();
cout << func0(test, 1, 2) << endl;
cout << func1(1, 2) << endl;
cout << func2(1, 2) << endl;
return 0;
}
코드 보시면 쉽게 이해하셨겠지만 이 예제에 대한 결과 값은 모두 3입니다.
mem_fn는 C++ 11에서 추가되었으며 쉽게 이야기하여 클래스 함수에 대한 포인터 호출을 편하게 하여줍니다. 예제에서 타입을 auto로 한 것은 mem_fn는 클래스 함수 포인터 형태를 리턴하기 때문에 문법적으로 편하게 적기 위해서 였습니다.
bind는 C++ 11에서 추가되었으며 클래스 함수를 사용할 때 인자 부분에 대해서 직접 지정하지 않을 시에는 placeholders를 지정하여 입력을 받을 수 있게 하여야 합니다. 그리고 인자의 개수는 placeholders의 개수와 같습니다.
bind_front는 C++ 20에서 추가되었으며 bind의 편의성 버전이라고 보시면 됩니다. 함수에서 필요한 인자의 앞부분만 채워서 클로저를 만드는 관계로 bind처럼 별도의 placeholders를 지정할 필요가 없으며 인자의 개수는 앞에서 부터 채운 뒤 남은 인자의 개수가 됩니다.
추가적인 설명을 하자면 클래스 함수에 대한 클로저는 모두 첫번째 인자로 클래스 객체에 대한 인스턴스 주소를 필요로 합니다. 다음으로 이 함수들은 클로저 호출 인자나 템플릿 프로그래밍에서 많이 사용됩니다.
참고로 기존에 사용하던 bind1st, bind2nd는 C++ 17에서 제거되었습니다. 이 함수들은 bind나 bind_front로 쉽게 구현 가능합니다.
'C++ 프로그래밍' 카테고리의 다른 글
C++ system_clock을 이용하여 64bit tick값 저장 및 로드 예제 (0) | 2022.03.28 |
---|---|
C++ 람다를 활용하여 함수 내 중복 코드 줄이기 (0) | 2022.03.23 |
C++ 람다 사용시 변수 캡처 주의점과 shared_ptr의 활용 (0) | 2022.01.21 |
C++ string_view의 이해와 활용 (0) | 2022.01.15 |
C++ 전역 객체 혹은 정적 객체 간의 생성 및 소멸 순서 문제 (0) | 2021.12.09 |
C++ using namespace를 헤더 파일에 사용하지 말자 (0) | 2021.12.01 |
C++ 람다에서 참조 값과 복사 값 동시에 사용하기 (0) | 2021.11.29 |
std::chrono::steady_clock 관련 종합 예제 (0) | 2021.11.22 |