씹어먹는 C++
15장 함수 객체 705p-718p
( )
를 붙여서 호출(call) 할 수 있는 모든 것
함수, 객체, 람다 함수 etc.
함수 뿐만이 아니라 모든 Callable 들을 보관할 수 있는 객체
템플릿 인자로 전달 받을 함수의 타입(리턴값과 함수 인자들)을 갖음
std::function<리턴값(함수인자)> [이름] = [받을 callable];
example code
#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();
}
Func1 호출! hello
Func2 호출! c
Func3 호출!
멤버 함수
example code
#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;
std::function<int(const A&)> f2 = &A::some_const_function;
f1(a);
f2(a);
}
비상수 함수: 6
상수 함수: 6
std::mem_fn
전달된 멤버 함수를 function 객체로 만들어서 리턴
즉 멤버 함수들을 함수 객체로 만들어 전달
example code
#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);
//mem_fn을 통해 간단히 멤버 함수를 넘김
transform(container.begin(), container.end(), size_vec.begin(),std::mem_fn(&vector<int>::size));
/*람다 함수로도 가능
std::mem_fn(&vector<int>::size)
= [](const auto&v){ return v.size()}
*/
for (auto itr = size_vec.begin(); itr != size_vec.end(); ++itr) {
std::cout << "벡터 크기 :: " << *itr << std::endl;
}
}
벡터 크기 :: 1
벡터 크기 :: 2
벡터 크기 :: 3
벡터 크기 :: 4
원래 함수에 특정 인자를 붙여(bind) 줌
함수 객체 생성 시에 인자를 특정한 것으로 지정
example code
#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() {
//add 함수의 첫번째 인자로 2를 bind
auto add_with_2 = std::bind(add, 2, std::placeholders::_1);
//두번째 인자로 새롭게 만들어진 함수 객체의 첫번째 인자 전달
add_with_2(3);
// 여러 인자 전달시 필요한 인자 이후는 다 무시된다.
add_with_2(3, 4);
//placeholders_1, _2 -> 일일히 정의된 객체들
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 를 계산한다
}
2 + 3 = 5
2 + 3 = 5
3 - 2 = 1
2 - 4 = -2
※ 레퍼런스를 인자로 받는 함수 유의
bind 함수로 인자가 복사 되서 전달
따라서 명시적으로 레퍼런스 전달이 필요
// 명시적 레퍼런스 전달 std::ref() 사용
auto do_something_with_s1 = std::bind(do_something, std::ref(s1), std::placeholders::_1);