C++ 프로그래밍

C++ 클래스 함수 간접 호출 : mem_fn, bind, bind_front

하늘흐늘 2021. 12. 11. 18:08
반응형

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로 쉽게 구현 가능합니다.

반응형