반응형
반응형

1. 바인더

  1. 이항 함수자를 단항 함수자로 변환
  2. STL은 두 가지 바인더 제공
    • bind1st : 첫번 째 인자 고정
    • bind2nd : 두번 째 인자 고정
  3. 예제
    • less 첫 번째 인자를 10으로 고정
   // less의 첫 인자를 10으로 고정한 binder
   binder1st<less<int>> binder = bind1st(less<int>(), 10);
   binder(5); // => less<int>()(10,5) 와 동일

   // 임시 객체로 사용
   bind1st(less<int>(), 10)(5);
  1. c++11 에서 비추 , c++17 에서 삭제됨
    • std::bind를 대신 사용하자.

2. 부정자(negator)

  1. 조건자를 반대의 조건자로 변환
  2. STL은 두 가지 부정자 제공
    • not1 : 단항 조건자를 변환
    • not2 : 이항 조건자를 변환
  3. 예제
    • less 조건자를 반대 조건자로 변환
less<int> oLess;
binary_negate<less<int>> negate = not2(less<int>());
// 아래 세 방법은 모두 동일
negate(5, 10);
not2(oLess)(5,10);
not2(less<int>())(5, 10);
// 5 < 10 의 반대는 5 => 10 이므로 false

3. 함수 포인터 어댑터

  1. 일반 함수를 어댑터 적용 가능한 함수 객체로 변환
    • 일반 함수는 STL 어댑터에 적용 안됨
    • 어댑터에 적용 가능한 함수 객체로 변환
  2. STL은 아래 함수 포인터 어댑터 제공
    • ptr_fun()
  3. 사용 예시
    • 사용자 정의 함수를 변환
bool Pred(int n){
   return 30 <= n && n <= 40;
}

vector<int> v = {10,20,30,40,50};
//30이상 40이하의 원소 개수 => 2
count_if(
   v.begin(),
   v.end(),
   Pred);

// 30이상 40이하가 아닌 원소 개수 => 3
count_if(
   v.begin(),
   v.end(),
   not1(ptr_fun(Pred)));
  1. 사용자 정의 ptr_fun 구현
template<typename RType, typename AType>
class Ptr_fun_class:public unary_function<AType, RType>{
   RType (*pf)(AType);
public:
   Ptr_fun_class(RType (*_pf)(AType))
      : pf(_pf) {}
   RType operator()(AType n) const{
      return pf(n);
   }
}

// 일반 함수를 함수 객체로 변환하는 Ptr_fun() 함수
template<typename RType, typename Atype>
Ptr_func_class<RType,AType> Ptr_fun(
   RType (*pf)(Atype) {
      return Ptr_fun_class<Rtpye, AType>(pf);
   }
)

4. 멤버 함수 포인터 어댑터

  1. 멤버 함수를 함수 객체로 변환
  2. 알고리즘이 객체 원소의 멤버 함수 호출 가능
  3. STL은 두 가지 멤버 함수 포인터 어댑터 제공
    • mem_fun_ref() : 객체로 멤버 함수 호출
    • mem_fun() : 객체의 주소로 멤버 함수 호출
  4. mem_fun_ref() 예시
vector<Point> v;
v.push_back(Point(1,1));
v.push_back(Point(2,2));
v.push_back(Point(3,3));
v.push_back(Point(4,4));
v.push_back(Point(5,5));

// 멤버 함수 호출 불가능
for_each(
   v.begin(), v.end(),
   &Point::Print);

// 멤버 함수 호출 가능
for_each(
   v.begin(), v.end(),
   mem_fun_ref(&Point::Print));
  1. 사용자 정의 Mem_fun_ref 예시
template<typename RType, typename CType>
class Mem_fun_ref_class:public unary_function<CType, RType>{
   RType (CType::*pf)() const;
public:
   Mem_fun_ref_class(RType (CType::*_pf)() const)
      : pf(_pf) {}
   RType operator()(const CType& o) const{
      return (o.*pf)();
   }
}

// 어댑터 함수 : 멤버 함수를 주소를 저장하는 함수 객체로 반환
template<typename RType, typename CType>
Mem_fun_ref_class<RType, CType> Mem_fun_ref(
   RType (CType::*pf() const){
      return Mem_fun_ref_class<RType,CType>(pf);
   }
)
  1. mem_fun() 어댑터 예시
    • 원소가 객체의 주소 일 때 사용
vector<Point*> v;
v.push_back(new Point(1,1));
v.push_back(new Point(2,2));
v.push_back(new Point(3,3));
v.push_back(new Point(4,4));
v.push_back(new Point(5,5));

for_each(
   v.begin(),
   v.end(),
   mem_fun(&Point::Print)
);

참고

  1. 뇌를 자극하는 C++ STL
반응형

'C++ > STL' 카테고리의 다른 글

[STL-18] 컨테이너 어댑터  (0) 2021.03.14
[STL-17] 반복자  (0) 2021.03.14
[STL-15] 함수 객체 - 비교/논리 연산 조건자  (0) 2021.03.14
[STL-14] 함수 객체 - 산술 연산 함수 객체  (0) 2021.03.14
[STL-13] 함수 객체 - 개요  (0) 2021.03.14
반응형

1. STL에서 제공하는 연산 조건자

  1. 비교 연산 조건자
    • 아래 함수 객체는 모두 이항 조건자
함수명 내용
equal_to<T> ==
not _equal_to<T> !=
less<T> <
less_equal<T> <=
greater<T> >
greater_equal<T> >=
  1. 논리 연산 조건자
함수명 내용 인자
logical_and<T> && 이항
logical_or<T> || 이항
logical_not<T> ! 단항

2. 연산 조건자 사용 법

  1. less<T>
    • 헤더 추가 : <functional>
    • 일반적으로 아래 방법 사용
    • less<int>()(10, 20);
less<int> oLess;   // 객체 생성

// 1. 암묵적 호출
oLess(10, 20);

// 2. 명시적 호출
oLess.operator()(10,20);

// 3. 임시 객체로 암묵적 호출(일반적인 사용)
less<int>()(10,20);

// 4. 임시 객체로 명시적 호출
less<int>().operator()(10,20);
  1. logical_and
    • 헤더 추가 : <functional>
int n = 30;
logical_and<bool> oAnd;

// 1. 암묵적 호출
oAnd(
   greator<int>()(n,10),
   less<int>()(n, 50)
);
// n이 10보다 크고, 50 보다 작은가? true

// 2. 명시적 호출
oAnd.operator()(
   greator<int>()(n,10),
   less<int>()(n, 50)
);

// 3. 임시 객체로 암묵적 호출(일반적 사용)
logical_and<bool>()(
   greator<int>()(n,10),
   less<int>()(n, 50)
);

// 4. 임시 객체로 명시적 호출
logical_and<bool>().operator()(
   greator<int>()(n,10),
   less<int>()(n, 50)
);

3. 사용자 정의 구현

  1. less
    • binary_function 상속
    • 첫번째 , 두번째 인자 : T
    • 리턴 인자 : bool
    • operator 함수는 const
template<typename T>
struct Less: public binary_function<T,T,bool>{
   bool operator()(const T& left, const T& right) const{
      return left < right;
   }
};

2. logical_and
```cpp
template<typename T>
struct Logical_and: public binary_function<T,T,bool>{
   bool operator()(const T& left, const T& right) const{
      return left && right;
   }
}

4. 알고리즘과 같이 사용하는 예

  1. count_if 로 같이 사용 예
    • count_if는 단항 조건자를 요구
    • bind2nd<T> 어댑터 사용하여 이항 조건자를 단항 조건자로 변경
vector<int> v = {10,20,30,40,50};
// 1. 20보다 작은 원소 개수
count_if(
   v.begin(),
   v.end(),
   bind2nd<less<int>>(
      less<int>(), 20
      )
);
// 1개

// 2. 20보다 작거나 같은 원소 개수
count_if(
   v.begin(),
   v.end(),
   bind2nd<less_equal<int>>(
      less_equal<int>(), 20
      )
);
// 2 개

// 3. 20보다 큰 원소 개수
count_if(
   v.begin(),
   v.end(),
   bind2nd<greater<int>>(
      greater<int>(), 20
      )
);
// 3개

// 4. 20보다 크거나 같은 원소 개수
count_if(
   v.begin(),
   v.end(),
   bind2nd<greater_equal<int>>(
      greater_equal<int>(), 20
      )
);
// 4개

// 5. 20과 같은 원소 개수
count_if(
   v.begin(),
   v.end(),
   bind2nd<equal_to<int>>(
      equal_to<int>(), 20
      )
);
// 1 개

// 5. 20과 다른 원소 개수
count_if(
   v.begin(),
   v.end(),
   bind2nd<not_equal_to<int>>(
      not_equal_to<int>(), 20
      )
);
// 4 개

참고

  1. 뇌를 자극하는 C++ STL
반응형

'C++ > STL' 카테고리의 다른 글

[STL-17] 반복자  (0) 2021.03.14
[STL-16] 함수 객체 - 함수 어댑터  (0) 2021.03.14
[STL-14] 함수 객체 - 산술 연산 함수 객체  (0) 2021.03.14
[STL-13] 함수 객체 - 개요  (0) 2021.03.14
[STL-12] 알고리즘7-수치 알고리즘  (0) 2021.03.14
반응형

1. STL에서 제공하는 산술 연산 함수 객체

함수명 내용 인자
plus<T> 더하기 이항
minus<T> 빼기 이항
multiplies<T> 곱하기 이항
divides<T> 나누기 이항
modulus<T> 나머지 이항
negate<T> 부호 변경 단항

2. 사용 법

  1. plus<T>
    • 헤더 추가 : <functional>
    • 일반적으로 아래 방법 사용
    • plus<int>()(10, 20);
plus<int> Plus;   // 객체 생성

// 1. 암묵적 호출
oPlus(10, 20);

// 2. 명시적 호출
oPlus.operator()(10,20);

// 3. 임시 객체로 암묵적 호출(일반적인 사용)
plus<int>()(10,20);

// 4. 임시 객체로 명시적 호출
plus<int>().operator()(10,20);

3. 알고리즘과 같이 사용하는 예

vector<int> v1 = {10,20,30,40,50};
vector<int> v2 = {1,2,3,4,5};
vector<int> v3(5);

//1. plus<int>()
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), plus<int>());
// v3 = {11,22,33,44,55}

//2. multiplies<int>()
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), multiplies<int>());
// v3= {10, 40, 90,  160, 250}

//3. negate<int>() : 부호 변경
transform(v1.begin(), v1.end(), v3.begin(), negate<int>());
// v3 = {-10, -20, -30, -40, -50}

// 4. minus<int>() + 인접 원소와의 차이
adjacent_difference(
   v1.begin(),
   v1.end(),
   v3,begin(),
   minus<int>()
);
// v3 = {10, 10, 10, 10, 10}

// 5.multiplies<int>() + 곱 누적
partial_sum(
   v1.begin(),
   v1.end(),
   v3.begin(),
   multiplies<int>()
);
// v3 = {10, 200, 6000, 240000, 12000000}

// 6.multiplies<int>() + 모든 원소 곱
int mul = accumulate(
   v1.begin(),
   v1.end(),
   1,
   muliplies<int>()
);
// mul = 12000000

참고

  1. 뇌를 자극하는 C++ STL
반응형
반응형

1. 용어 정리

  1. 함수 객체란?
    • operator() 연산자를 오버로딩한 클래스 객체
    • 다른 이름으로 functor(함수자)라고 불림
  2. 함수류 : 함수 객체, 함수, 함수 포인터

2. 함수 객체 종류

  1. 일반 함수 객체 : 특정 기능을 수행

    • 산술 연산 함수 객체 : 산술 연산 기능 수행
    • 비교 연산 함수 객체 조건자 : 비교 조건자
  2. 함수 어댑터 : 함수류를 인자로 받아 다른 함수 객체로 변환

    • 바인더: 이항 함수 객체를 단항 함수 객체로 변환
    • 부정자 : 함수 객체 조건자를 반대로 변환
    • 함수 포인터 어댑터 : 함수 포인터를 STL이 요구하는 함수 객체로 변환
    • 멤버 함수 포인터 어댑터 : 멤버 함수 포인터를 함수 객체로 변환

3. 조건자

  1. bool 형식을 반환하는 함수류
    • 함수 객체 조건자
    • 함수 조건자
    • 함수 포인터 조건자
  2. STL에서 조건자?
    • 모두 함수 객체 조건자
    • 조건자는 객체의 상태값을 변경할 수 없음
    • operator() 연산자 오버로딩 함수는 모두 const

4. 어댑터

  1. 함수 객체를 다른 함수 객체로 변환할 때 사용
  2. 어댑터 인자로 사용되는 단항 함수 필요 조건
    • argument_type 정의 필요
    • result_type 정의 필요
  3. 어댑터 인자로 사용되는 이항 함수 필요 조건
    • first_argument_type 정의
    • second_argument_type 정의
    • result_type 정의
template<typename T>
struct Plus{
   typedef T first_argument_type;
   typedef T second_argument_type;
   typedef T result_type;

   T operator()(const T& left, const T& right) const{
      return left + right;
   }
};

vector<int> v1 = {10,20,30};
vector<int> v3(3);

// Plus 함수를 단항 함수로 변경
transform(
   v1.begin(),
   v1.end(),
   v3.begin(),
   binder1st<Plus<int>> (Plus<int>(), 100)
   );
// v3 = {110, 120 , 130}
  1. 단항, 이항 함수 형식 정의 방법
    • 위 조건 정의 대신 아래 클래스 상속
    • unary_function : 단항 함수 정의시
    • binary_function : 이항 함수 정의시
template<typename T>
struct Plus: public binary_function<T,T,T>{
   T operator()(const T& left, const T& right) const{
      return left+right;
   }
};

vector<int> v1 = {10,20,30};
vector<int> v3(3);

// Plus 함수를 단항 함수로 변경
transform(
   v1.begin(),
   v1.end(),
   v3.begin(),
   binder1st<Plus<int>> (Plus<int>(), 100)
   );
// v3 = {110, 120 , 130}

참고

  1. 뇌를 자극하는 C++ STL
반응형

+ Recent posts

반응형