On this page
article
std::bind
개념
std::bind
는 callable 객체의 일부 인자를 고정한 새로운 함수 객체를 생성하는 도구- C++ 표준에서 타입을 명확히 지정하지않았으나 operator() 연산자를 재정의한 함수 객체
- 일반 함수, 멤버 함수, 함수 객체, 람다 모두에 사용 가능
- C++11에서 도입
예시
using namespace std::placeholders;
void foo(int a, int b, int c, int d) {
std::println("{} {} {} {}", a, b, c, d);
}
auto f1 = std::bind(&foo, 1, 2, 3, 4);
f1(); // foo(1, 2, 3, 4)
auto f2 = std::bind(&foo, 9, _1, 8, _2);
f2(5, 7); // foo(9, 5, 8, 7)
std::ref
- 참조 전달이 필요한 경우
std::ref(n)
사용
void foo(int& a);
auto f1 = std::bind(&foo, std::ref(n));
인자로 가능한 형태
- 일반 인자
std::ref_wrapper
std::placeholders
(_1
,_2
…)- 다른
bind expression
Bind Expression
std::bind
를 또 다른std::bind
의 인자로 넘기는 방식
int mul(int a, int b) { return a * b; }
int add(int a, int b) { return a + b; }
auto f1 = std::bind(&mul, std::bind(&add, _1, _2), 2);
// f1(x, y) == mul(add(x, y), 2)
개선
→ 2번째 인자가 std::is_bind_expression_v
If T is a type produced by a call to std::bind (but not std::bind_front or std:: bind_back), this template is derived from std::true_type. For any other type (unless user-specialized), this template is derived from std::false_type.
int mul(int a, int b) { return a * b; }
struct Add
{
int operator()(int a, int b) const { return a + b;}
};
template<>
struct std::is_bind_expression<Add> : public std::true_type{};
auto f1 = std::bind(&mul, Add{}, 2);
bind_front (C++20), bind_back (C++23)
std::bind
의 복잡성과_2
,_1
인덱싱의 혼란을 개선
auto f1 = std::bind(&foo, 0, 0, _1, _2);
auto f2 = std::bind_front(&foo, 0, 0); // 동일한 효과
auto f3 = std::bind(&foo, _1, _2, _3, 0);
auto f4 = std::bind_back(&foo, 0); // 마지막 인자 고정
요약
std::bind
는 인자를 고정해 새로운 callable 객체를 만들 수 있음- 중첩된 표현도 가능하지만 복잡해질 수 있음
- C++20 이후
std::bind_front
, C++23 이후std::bind_back
사용 권장