도순씨의 코딩일지

C++ :: STL 함수 객체(1) 본문

𝐏𝐑𝐎𝐆𝐑𝐀𝐌𝐌𝐈𝐍𝐆/𝐂++

C++ :: STL 함수 객체(1)

도순씨 2020. 11. 1. 00:00

🌼 함수 객체의 종류

함수 객체(function object)는 함수자와 같은 말로, operator() 연산자를 오버로딩한 클래스 객체입니다.

 

다음 예제는 함수 객체, 함수, 함수 포인터 조건자로 조건을 판단하는 예제입니다.

 

⭐️ 세 가지 조건자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
 
struct LessFunctor{     // 1. 함수 객체 조건자
    bool operator()(int left, int right) const{
        return left < right;
    }
};
 
bool LessFun(int left, int right){  // 2. 함수 조건자
    return left < right;
}
 
int main(void){
    bool (*LessPtr)(intint= LessFun;    // 3. 함수 포인터 조건자
    LessFunctor lessFunctor;
 
    cout << lessFunctor(1020<< endl;
    cout << LessFun(1020<< endl;
    cout << LessPtr(1020<< endl;
}
cs

 

⭐️ 세 가지 조건자 실행결과

1
2
3
1
1
1
cs

 

다음 예제는 transform을 사용하여 v1와 v2를 plus<int> 연산합니다.

 

⭐️ transform() 알고리즘의 plus<int> 연산

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
 
template <typename T>
struct Plus{
    T operator() (const T& left, const T& right) const {
        return left + right;
    }
};
 
int main(){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
 
    vector<int> v2;
    v2.push_back(1);
    v2.push_back(1);
    v2.push_back(1);
 
    vector<int> v3(3);
 
    // 사용자 정의 조건자 plus<int> 사용
    transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), Plus<int>());
 
    cout << "v1 : ";
    for(vector<int> :: size_type i = 0 ; i < v1.size() ; i++)
        cout << v1[i] << " ";
    cout << endl;
 
    cout << "v2 : ";
    for(vector<int> :: size_type i = 0 ; i < v2.size() ; i++)
        cout << v2[i] << " ";
    cout << endl;
 
    cout << "v3 : ";
    for(vector<int> :: size_type i = 0 ; i < v3.size() ; i++)
        cout << v3[i] << " ";
    cout << endl;
}
cs

 

⭐️ transform() 알고리즘의 plus<int> 연산 실행결과

1
2
3
v1 : 10 20 30 
v2 : 1 1 1 
v3 : 11 21 31 
cs

 

다음은 v1의 모든 원소에 100을 더하는 어댑터 적용 transform() 알고리즘 예제입니다.

 

⭐️ 어댑터를 사용한 transform() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
using namespace std;
 
template<typename T>
struct Plus{
    T operator() (const T& left, const T& right) const{
        return left + right;
    }
};
 
int main(void){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
 
    vector<int> v3(3);
    transform(v1.begin(), v1.end(), v3.begin(), binder1st <plus<int> > (plus<int>(), 100));
 
    cout << "v1 : ";
    for(vector<int>::size_type i = 0 ; i < v1.size() ; i++)
        cout << v1[i] << " ";
    cout << endl;
 
    cout << "v3 : ";
    for(vector<int>::size_type i = 0 ; i < v3.size() ; i++)
        cout << v3[i] << " ";
    cout << endl;
 
    return 0;
}
cs

 

⭐️ 어댑터를 사용한 transform() 알고리즘 실행결과

1
2
v1 : 10 20 30 
v3 : 110 120 130 
cs

 

🌼 산술 연산 함수 객체

STL은 여섯가지 산술 연산 함수 객체(함수자)를 제공합니다.

💡 plus<T> : 이항 연산 함수자, +

💡 minus<T> : 이항 연산 함수자, -

💡 multiplies<T> : 이항 연산 함수자, *

💡 devides<T> : 이항 연산 함수자, /

💡 modulus<T> : 이항 연산 함수자, %

💡 negate<T> : 단항 연산 함수자, -

 

다음은 이름 있는 개체와 임시 객체로 STL plus<T>를 사용한 것입니다.

 

⭐️ plus<T>의 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <functional>
using namespace std;
 
int main(void){
    plus<int> oPlus;
    // 1. oPlus 객체로 10, 20 더하기 암묵적 호출
    cout << oPlus(1020<< endl;
    // 2. oPlus 객체로 10, 20 더하기 명시적 호출
    cout << oPlus.operator()(1020<< endl;
 
    // 3. 임시 객체로 10, 20 더하기 암묵적 호출 (일반적인 사용)
    cout << plus<int>()(1020<< endl;
    // 4. 임시 객체로 10, 20 더하기 명시적 호출
    cout << plus<int>().operator()(1020<< endl;
 
    return 0;
}
cs

 

⭐️ plus<T>의 사용 실행결과

1
2
3
4
30
30
30
30
cs

 

다음 예제는 plus<T> 함수자처럼 구현한 사용자 Plus<T> 함수자입니다.

 

⭐️ 사용자 Plus<T>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <functional>
using namespace std;
 
template<typename T>
struct Plus : public binary_function<T, T, T>{
    T operator()(const T& left, const T& right) const{
        return left + right;
    }
};
 
int main(void){
    Plus<int> oPlus;
    cout << oPlus(1020<< endl;
    cout << oPlus.operator()(1020<< endl;
    
    cout << Plus<int>()(1020<< endl;
    cout << Plus<int>().operator()(1020<< endl;
 
    return 0;
}
cs

 

⭐️ 사용자 Plus<T> 실행결과

1
2
3
4
30
30
30
30
cs

 

 

🌼 비교 연산 조건자

다음은 여섯가지 비교 연산함수 객체 조건자입니다.

💡 equal_to<T> : 이항조건자, ==

💡 not_equal_to<T> : 이항조건자, !=

💡 less<T> : 이항조건자, <

💡 less_equal<T> : 이항조건자, <=

💡 greater<T> : 이항조건자, >

💡 greater_equal<T> : 이항조건자, >=

 

다음은 조건자 less<T> 사용 예제입니다.

 

⭐️ 조건자 less<T>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <functional>
using namespace std;
 
int main(void){
    less<int> oLess;
    // 1. oLess 객체로 10, 20을 비교 true. 암묵적 호출
    cout << oLess(1020<< endl;
    // 2. oLess 객체로 10, 20을 비교 true. 명시적 호출
    cout << oLess.operator()(1020<< endl;
 
    // 3. 임시 객체로 10, 20을 비교 true. 암묵적 호출 (일반적인 사용)
    cout << less<int>()(1020<< endl;
    // 4. 임시 객체로 10, 20을 비교 true. 명시적 호출
    cout << less<int>().operator()(1020<< endl;
 
    return 0;
}
cs

 

⭐️ 조건자 less<T> 실행결과

1
2
3
4
1
1
1
1
cs

 

다음은 조건자 less<T>처럼 구현한 사용자 Less<T> 조건자이다.

 

⭐️ 사용자 Less<T>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <functional>
using namespace std;
 
template <typename T>
struct Less : public binary_function<T, T, bool>{
    bool operator()(const T& left, const T& right) const{
        return left < right;
    }
};
 
int main(void){
    Less<int> oLess;
    cout << oLess(1020<< endl;
    cout << oLess.operator()(1020<< endl;
 
    cout << Less<int>()(1020<< endl;
    cout << Less<int>().operator()(1020<< endl;
 
    return 0;
}
cs

 

⭐️ 사용자 Less<T> 실행결과

1
2
3
4
1
1
1
1
cs

 

🌼 논리 연산 조건자

세 가지 논리 연산 함수 객체 조건자를 소개하겠습니다.

💡 logical_and<T> : 이항연산자, &&

💡 logical_or<T> : 이항연산자, ||

💡 logical_not<T> : 단항연산자, !

 

⭐️ 논리 조건자 logical_and<T>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <functional>
using namespace std;
 
template <typename T>
struct Logical_and: public binary_function<T, T, bool>{
    bool operator()(const T& left, const T& right) const{
        return left && right;
    }
};
 
int main(void){
    int n = 30;
    logical_and<bool> oAnd;
    
    // 1. oAnd 객체로 10 < n < 50 인가? true. 암묵적 호출
    cout << oAnd(greater<int>()(n, 10), less<int>()(n, 50)) << endl;
    // 2. oAnd 객체로 10 < n < 50 인가? true. 명시적 호출
    cout << oAnd.operator()(greater<int>()(n, 10), less<int>()(n, 50)) << endl;
    // 3. 임시 객체로 10 < n < 50인가? true. 암묵적 호출(일반적인 사용)
    cout << logical_and<bool>()(greater<int>()(n, 10), less<int>()(n, 50)) << endl;
    // 4. 임시 객체로 10 < n < 50인가? ture. 명시적 호출
    cout << logical_and<bool>().operator()(greater<int>()(n, 10), less<int>()(n, 50)) << endl;
 
    return 0;
}
cs

 

⭐️ 논리 조건자 logical_and<T> 실행결과

1
2
3
4
1
1
1
1
cs

 

🌼 바인더

💡 bind1st : 이항 함수자의 첫 번째 인자를 고정하여 단항 함수자로 변환

💡 bind2nd : 이항 함수자의 두 번째 인자를 고정하여 단항 함수자로 변환

 

다음 예제는 이항 조건자를 단항 조건자로 변환하는 바인더 예제입니다.

 

⭐️ bind1st 바인더

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <functional>
using namespace std;
 
int main(void){
    // 첫 인자를 10으로 고정
    binder1st<less<int>> binder = bind1st (less<int>(), 10);
 
    cout << binder(5<< ':' << less<int>()(105<< endl;
    cout << binder(10<< ':' << less<int>()(1010<< endl;
    cout << binder(20<< ':' << less<int>()(1020<< endl;
 
    cout << "==== 위와 같음 ====" << endl;
 
    // 임시 객체 사용
    cout << bind1st(less<int>(), 10) (5<< ':' << less<int>()(105<< endl;
    cout << bind1st(less<int>(), 10) (10<< ':' << less<int>()(1010<< endl;
    cout << bind1st(less<int>(), 10) (20<< ':' << less<int>()(1020<< endl;
 
}
cs

 

⭐️ bind1st 바인더 실행결과

1
2
3
4
5
6
7
0:0
0:0
1:1
==== 위와 같음 ====
0:0
0:0
1:1
cs

 

 

Comments