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로 받고 함수를 호출해보자.
결과:
파라미터로 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();
결과:
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.
Leave a comment