함수 호출 연산자를 클래스에서 오버로딩하면 함수 포인터 자리에 넣을 수 있는 객체.
1. 산술 함수 객체
plus : +
minus : -
multiplies : *
divides : /
modulus : %
negate : ~
2. 비교 함수 객체
equal_to : ==
not_equal_to : !=
greater : >
less_equal : <=
greater_equal : >=
3. 논리 함수 객체
logical_not : !
logical_and : &&
logical_or : ||
4. 비트 연산 함수 객체
bit_and : &
bit_or : |
bit_xor : ^
5. 함수 객체 어댑터
함수 객체를 이용할 때, 인터페이스가 맞지 않는 경우 함수를 합성하거나 조합하여 필요한 함수형태를 만듦
5.1 바인더
함수의 특정 파라미터를 특정 값으로 묶어둘 수 있다.
bind() / C++11
ex)
void func (int num, const std::string& str)
{
std::cout << num << str << std::endl;
}
std::string str = "abc";
auto f1 = std::bind(func, std::placeholder::_1, str);
f1(16);
bind1st(), bind2nd()
ex)
std::vector<int>::iterator end = myVector.end();
std::vector<int>::iterator it = find_if(myVector.begin(), end, std::bind2nd(std::greater_equal<int>(), 100));
if (it == end) {
std::cout << "no perfect scores" << std::endl;
} else {
std::cout << "found a perfect score of" << *it << std::endl;
}
5.2 부정연산
바인더와 비슷하지만 프레디킷(조건 검사 콜백 함수)의 결과를 반전시킨다.
ex)
auto end = myVector.end();
auto it = find_if(myVector.begin(), end, std::not1(std::bind2nd(std::greater_equal<int>(), 100)));
if (it == end) {
std::cout << "All perfect scores" << std::endl;
} else {
std::cout << "Found a less than perfact score of" << *it << std::endl;
}
C++11이후로는 람다를 이용한 구현을 권장한다.
ex)
auto it = std::find_if(myVector.begin(), end, [](int i) { return i < 100; });
5.3 멤버 함수의 호출
C++11은 멤버 함수의 포인터를 알고리즘에서 호출할 수 있도록 변환 함수 mem_fn()을 제공한다.
ex)
void findEmptyString(const std::vector<std::string>& strings)
{
auto end = strings.end();
// 컨테이너에 객체 or 객체의 포인터가 저장되어 있어도 동일함수 사용
auto it = std::find_if(std::strings.begin(), end, mem_fn(&std::string::empty());
if (it == end) {
std::cout << "No empty strings!" << std::endl;
} else {
std::cout << "Empty string at position" << it - strings.begin() << endl;
}
}
C++11 이전 버전에서는 mem_fun_ref(객체) / mem_fun(객체의 포인터) 함수를 이용해야한다
하지만 C++11 람다 표현식을 이용하면 훨씬 구현하기 쉽고 이해하기 쉽다.
ex)
void findEmptyString(const vector<string>& strings)
{
auto end = strings.end();
auto it = find_if(strings,begin(), end, [](const string& str) { return str.empty(); });
}
void findEmptyString(const std::vector<std::string>& strings)
{
auto end = strings.end();
auto it = std::find_if(strings,begin(), end, [](const std::string& str) { return str.empty(); });
}
'프로그래밍 > C,C++' 카테고리의 다른 글
유틸리티 라이브러리 (0) | 2018.04.18 |
---|---|
문자열과 정규 표현식 (0) | 2018.04.15 |
람다(lambda) (0) | 2018.04.11 |
STL 알고리즘 (0) | 2018.04.02 |
STL 컨테이너 (0) | 2018.04.02 |