C++
에서는 ()
를 붙여서 호출할 수 있는 모든 것을 의미연산자 ()
#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);
}
a + b = 8
람다함수
#include <iostream>
int main() {
auto f = [](int a, int b) { std::cout << "a + b = " << a + b << std::endl; };
f(3, 5);
}
a + b = 8
Callable
들을 객체의 형태로 보관할 수 있는 클래스 제공Callable
들을 보관할 수 있는 객체#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();
std::function<void()> f3 = []() { std::cout << "Func3 호출! " << std::endl; };
f1("hello");
f2('c');
f3();
}
function
객체는 템플릿 인자로 전달 받을 함수의 타입을 가짐Functor
인 클래스 S
의 객체의 경우 단순히 S
의 객체를 전달해도 이를 마치 함수 인양 받게 됨operator()
가 인자로 char
을 받고 리턴타입이 void
이므로 std::function<void(char)>
의 꼴로 표현할 수 있게 됨this
의 경우 자신을 호출한 객체를 의미하기 때문에, 만일 멤버함수를 그냥 function에 넣게 된다면 this
가 무엇인지 알 수 없는 문제가 발생&
연산자를 통해 명시적으로 주소값을 전달해야 함#include <functional>
#include <iostream>
#include <string>
class A {
int c;
public:
A(int c) : c(c) {}
int some_func() {
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&)> f1 = &A::some_func; //인자로 자신인 A class 전달
std::function<int(const A&)> f2 = &A::some_const_function;
f1(a);
f2(a);
}
function
객체로 만들어 리턴해줌#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
using std::vector;
int main() {
vector<int> a(1);
vector<int> b(2);
vector<int> c(3);
vector<int> d(4);
vector<vector<int>> container;
container.push_back(a);
container.push_back(b);
container.push_back(c);
container.push_back(d);
vector<int> size_vec(4);
transform(container.begin(), container.end(), size_vec.begin(),
std::mem_fn(&vector<int>::size)); //매개함수로 function객체를 넘겨주기 위해 mem_fn사용
for (auto itr = size_vec.begin(); itr != size_vec.end(); ++itr) {
std::cout << "벡터 크기 :: " << *itr << std::endl;
}
}
원래 함수에 특정 인자를 붙여(bind)줌
예시코드
#include <functional>
#include <iostream>
void add(int x, int y) {
std::cout << x << " + " << y << " = " << x + y << std::endl;
}
void subtract(int x, int y) {
std::cout << x << " - " << y << " = " << x - y << std::endl;
}
int main() {
auto add_with_2 = std::bind(add, 2, std::placeholders::_1);
add_with_2(3);
// 두 번째 인자는 무시된다.
add_with_2(3, 4);
auto subtract_from_2 = std::bind(subtract, std::placeholders::_1, 2);
auto negate =
std::bind(subtract, std::placeholders::_2, std::placeholders::_1);
subtract_from_2(3); // 3 - 2 를 계산한다.
negate(4, 2); // 2 - 4 를 계산한다
}
auto add_with_2 = std::bind(add, 2, std::placeholders::_1);
add
라는 함수에 첫 번째 인자로 2를 bind
시켜주고, 두 번째 인자로는 새롭게 만들어진 함수 객체의 첫 번째 인자를 전달add_with_2(3);
add
함수의 첫 번째 인자로는 2가 들어가게 되고, 두 번째 인자로 add_with_2
의 첫번째 인자인 3이 들어감add_with_2(3, 4);
auto negate = std::bind(subtract, std::placeholders::_2, std::placeholders::_1);
bind
함수로 인자가 복사되어 전달하기 때문에 const가 아니라면 레퍼런스를 전달해야 됨을 주의하자