std::bind와 Ref 사용 주의

🦥 std::bind?

함수 탬플릿 std::bind는 함수포인터에 대한 전달 호출 레퍼를 생성한다. 이 레퍼를 호출하는 것은 일부 인수를 args에 바인딩 하여 함수포인터를 호출 하는 것과 같다.

주의점

바인딩하는 인수는 복사되거나 이동된다. std::ref또는 std::cref로 래핑되지 않는 한 참조로 전달되지 않는다.

참조를 의도 했지만 std::ref나 std::cref를 안 쓰면 참조가 아니게 된다.

확인

#include <functional>
#include <iostream>
#include <string>
using namespace std;

void func1(int& a, int& b) {
	cout << "a: " + to_string(a) + " b: " + to_string(b) << endl;
}

int main()
{
	int a = 0;
	int b = 100;
	auto f = bind(func1, a, b);

	f();
	a = 100;
	b = 0;
	f();

	return 0;
}

파라미터를 ref로 받고 함수를 호출해보자.

결과:

image-20240302154105649

파라미터로 ref를 사용했지만, a와 b는 변화가 없다.

코드 수정:

	int a = 0;
	int b = 100;
	auto f = bind(func1, std::ref(a), std::ref(b));

	f();
	a = 100;
	b = 0;
	f();

결과:

image-20240302154415515

a는 100 b는 0으로 바뀐걸 알 수 있다. 콜백을 구현할 때 인자를 ref로 할거면 신경써줘야 한다.

References

Notes

As described in Callable, when invoking a pointer to non-static member function or pointer to non-static data member, the first argument has to be a reference or pointer (including, possibly, smart pointer such as std::shared_ptr and std::unique_ptr) to an object whose member will be accessed.

The arguments to bind are copied or moved, and are never passed by reference unless wrapped in std::ref or std::cref.

Duplicate placeholders in the same bind expression (multiple _1’s for example) are allowed, but the results are only well defined if the corresponding argument (u1) is an lvalue or non-movable rvalue.

Cpp래퍼런스

Leave a comment