std::bind함수에 대해 정리해보는 문서다.
[함수 포인터 정리글] 여기서 정리했듯이
c+11부터 #include<functional>, std::function을 이용해 함수의 포인터를 정의할 수 있다.
int Test(int x,int y) {
cout << x+y;
return x + y;
}
x,y두개의 매개변수를 받아서 더한값을 출력하고 x+y를 리턴하는 함수가 있다고 하자.
std::function<int(int, int)> f = Test;
이런식으로 std::function을 통해 함수포인터를 만들어서 할당받을 수 있다.
클래스의 멤버함수로도 사용할 수 있다.
class apple {
public:
apple() {
cout<<"Init"<<'\n';
}
~apple() {
cout << "deleting" << '\n';
}
apple(const apple& other) {
cout << "Copying"<<'\n';
}
void Shout(int x,int y) {
cout << "I have" <<x+y<< "apples!!!!" << '\n';
}
};
이런 클래스가 있을 때,
shout을 함수포인터로 생성하려면
apple a;
function<void( apple&,int,int)> f = &apple::Shout;
이런식으로 function의 매개변수에 어떤 클래스인지 참조자를 통해 넣어준다.
또한 기본적으로 함수들은 함수의 이름이 주소값으로 암시적 변환이 일어나지만, 멤버함수들은 암시적 변환이 일어나지 않는다.
따라서 멤버함수를 참조자를 통해 멤버변수의 주소를 넘겨야한다.
위의 함수포인터에서 매개변수를 고정시킬 수가 있는데
바로 std::bind이다.
std::function<int(int)> f=std::bind(Test,std::placeholders::_1,2);
이 코드의 의미는 Test함수에서 첫번째 인자가 2인 함수 f를 만든 것이다.
std::placeholders는 _1, _2, _3를 통해 몇번째 인자인지 결정해준다.
첫번째 인자는 2로 고정시켰으므로 f는 한 인자만 받으면 돼서
function<int(int)> f
의 형태이다.
따라서 f(3)을 실행해보면 5가 출력되고 5가 반환된다.
클래스의 멤버함수에 대해서도 bind를 사용할 수 있다.
클래스 내부에서 bind해주는 멤버함수를 작성하면 편리하다.
class apple {
public:
apple() {
cout<<"Init"<<'\n';
}
~apple() {
cout << "deleting" << '\n';
}
apple(const apple& other) {
cout << "Copying"<<'\n';
}
void Shout(int x,int y) {
cout << "I have" <<x+y<< "apples!!!!" << '\n';
}
void BindShout(function<void(int)>& other) {
other = std::bind(&apple::Shout, this,std::placeholders::_1, 2);
}
};
BindShout 멤버함수는 int형 매개변수 하나만 가진 함수포인터를 인자로 받는다.
&apple::Shout과 this를 통해 현재 apple클래스의 Shout함수를 other에 할당시키고, 첫번째 인자 x를 2로 고정시킨다.
apple a;
function<void(int)> f;
a.BindShout(f);
f(3);
이렇게 실행하면 5가 출력된다.
https://yhwanp.github.io/2019/09/15/std-function-and-std-bind/