C++에서는 ()를 붙여서 호출할 수 있는 모든 것을 Callable이라고 정의한다.
Callable 예시
#include <iostream>
struct S {
void operator()(int a, int b) { std::cout << "a + b = " << a + b << std::endl; }
};
int main() {
S some_obj;
some_obj(3, 5); // some_obj는 함수가 아닌 객체 // callable
auto f = [](int a, int b) { std::cout << "a + b = " << a + b << std::endl; };
f(3, 5); // callable
}
std::function
Callable들을 객체의 형태로 보관할 수 있는 클래스 std::function
#include <functional>
#include <iostream>
#include <string>
int some_func1(const std::string& a) {
std::cout << "Func1 호출! " << a << std::endl;
return 0;
}
struct S {
void operator()(char c) { std::cout << "Func2 호출! " << c << std::endl; }
};
int main() {
std::function<int(const std::string&)> f1 = some_func1; // 일반 함수
std::function<void(char)> f2 = S(); // Functor
std::function<void()> f3 = []() { std::cout << "Func3 호출! " << std::endl; }; // 람다 함수
f1("hello");
f2('c');
f3();
}
function 객체는 템플릿 인자로 전달 받을 함수의 타입 (리턴 값과 인자)를 받는다.
멤버 함수를 가지는 std::function
#include <functional>
#include <iostream>
#include <string>
class A {
int c;
public:
A(int c) : c(c) {}
int some_func(char ch) {
std::cout << "비상수 함수: " << ++c << std::endl;
return c;
}
int some_const_function() const {
std::cout << "상수 함수: " << c << std::endl;
return c;
}
static void st() {}
};
int main() {
A a(5);
std::function<int(A&, char)> f1 = &A::some_func;
std::function<int(const A&)> f2 = &A::some_const_function;
f1(a,'c');
f2(a);
}
멤버 함수를 function 객체에 담기 위해서는 함수의 원래 인자 앞에 객체를 받는 인자를 추가하면 된다.
멤버함수가 아닌 함수들의 경우 함수의 이름이 함수의 주소값으로 암시적 변환이 일어나지만, 멤버 함수의 주소는 &연산자를 통해 명시적으로 주소값을 전달해줘야 한다.
std::bind
원래 함수에 특정 인자를 지정할 수 있다. 첫 번째 인자에 특정한 값을 고정시킨 함수 객체를 만들거나 인자의 순서를 바꾼 함수 객체를 만들 수도 있다.
레퍼런스를 인자로 받는 함수에 레퍼런스를 전달하고 싶으면 인자를 std::ref()로 감싸 전달하면 된다.
참조:
'C++' 카테고리의 다른 글
C++ 키워드 정리 (0) | 2022.08.27 |
---|---|
C++ 동기와 비동기 (0) | 2022.08.26 |
C++ RAII와 스마트포인터 (0) | 2022.08.26 |
C++ 가상 함수, virtual 소멸자, 가상 함수 테이블, 추상 클래스 (0) | 2022.08.25 |
C++ 템플릿, 함수 객체(Functor) (0) | 2022.08.25 |