c+모방 함수 와 함수 어댑터 의 사용 에 대한 상세 한 설명
따라서 여기 에는 명확 한 두 가지 가 필요 하 다.
1.모방 함 수 는 함수 가 아니 라 클래스 입 니 다.
2.모방 함수 가()연산 자 를 다시 불 러 와 서 함수 처럼 호출 할 수 있 습 니 다.
for_each
여기 for 순환 문 구 는 좀 지루 해서 std::for 가 생각 났 습 니 다.each,for 를 사용 하기 위해each,우 리 는 함 수 를 정의 해 야 합 니 다.다음 과 같 습 니 다.
void print( State* pstate )
{
pstate->print();
}
그래서 다음 코드 로 간략화 할 수 있 습 니 다.std::for_each( vect.begin(), vect.end(), &print );
STL 은 크게 용기(container),알고리즘(algorithm),교체 기(iterator),모방 함수(functor),어댑터(adapter),설정 기(allocator)로 나 뉜 다.그 중에서 모방 함 수 는 부피 가 가장 작고 관념 이 가장 간단 하지만 stl 알고리즘 의 조합 에서 매우 중요 한 역할 을 하 는데 이것 은 간단 한 lambda 나 지침 함수 와 다르다.
stl 에서 plus,minus,multiplies,divides,modulus,equal 와 같은 유용 한 모방 함 수 를 대량으로 제공 합 니 다.to,not_equal_to,greater...많 습 니 다.들 어 오 는 매개 변수의 개수 에 따라 하나의 매개 변 수 를 받 아들 여야 하 는 모방 함수(unaryfunction)과 두 개의 인 자 를 받 아야 하 는 모방 함수(binaryfunction)。
모방 함수 구현 예시
// 1, template<typename T> struct comp
{
bool operator()(T in1, T in2) const
{
return (in1>in2);
}
};comp<int> m_comp_objext;
cout << m_comp_objext(6, 3) << endl; //
cout << comp<int>()(1, 2) << endl; //
위의 코드 에서 첫 번 째 호출 방식 은 cop 가 정의 한 대상 을 사용 한 다음 에 이 대상 을 통 해 조작 자()를 호출 하여 두 배열 의 비 교 를 실현 하 는 것 입 니 다.두 번 째 호출 cop()(1,2)는 임시(이름 없 는)대상 이 생 긴 다.2.2 모방 함수 상세 설명
아래 의 사용 장면(한 용기 의 규정 에 부합 되 는 요 소 를 통계)에서 앞서 언급 한 함수 포인터 가 왜 STL 에서 모방 함 수 를 교체 할 수 없 는 지 설명 합 니 다.
bool my_count(int num)
{
return (num < 5);
}int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> v_a(a, a+10);
cout << "count: " << std::count_if(v_a.begin(), v_a.end(), my_count);
위 에서 우 리 는 함수 지침 을 count 로 전달 했다.if 의 비교 조건.그러나 이 제 는 새로운 수요 에 따라 용기 에 있 는 5 이하 의 변수 개 수 를 집계 하지 않 고 8 또는 3 으로 바 꾸 었 다.그렇다면 가장 직접적인 방법 은 매개 변수 threshold 를 추가 하면 됩 니 다.아래 처럼.
bool my_count(int num, int threshold)
{
return (num < threshold));
}
그러나 이러한 표기 법 STL 에 서 는 사용 할 수 없 으 며,용기 에 있 는 요소 의 종류 가 바 뀌 었 을 때 사용 할 수 없 으 며,더욱 중요 한 것 은 템 플 릿 함 수 를 사용 할 수 없다 는 것 이다.그러면 다 중 전달 매개 변 수 를 사용 할 수 없 는 이상 전달 해 야 할 매개 변 수 를 전체적인 변수 로 설정 하면 현재 상황 에서 한도 값 조건 에 대한 수정 을 실현 할 수 있 지만 수정 할 때 위험 이 존재 합 니 다(초기 화 되 지 않 으 면 호출 하면 어떻게 합 니까?).그래서 이런 문 제 를 해결 하 는 방식 은
방식 이 STL 과 잘 호 환 되 었 습 니 다.
template<typename T> struct my_count1
{
my_count1(T a)
{
threshold = a;
}
T threshold;
bool operator()(T num)
{
return (num < threshold);
}
};int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> v_a(a, a+10);cout << "count: " << std::count_if(v_a.begin(), v_a.end(), my_count1<int>(8));
1.모방 함 수 를 정렬 기준 으로 한다.
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;class Person
{
public:
Person(string a, string b) :
strFirstname(a), strLastname(b)
{}
public:
string firstname() const
{
return strFirstname;
}
string lastname() const
{
return strLastname;
}
private:
const string strFirstname;
const string strLastname;
};//
class PersonSortCriterion
{
public:
//
// : lastname ,lastname firstname
bool operator()(const Person &p1, const Person &p2)
{
return (p1.lastname() > p2.lastname() ||
((p2.lastname() <= p1.lastname()) &&
p1.firstname() > p2.firstname()));
}
};
int main(int argc, char *argv[])
{
// ,
typedef set<Person, PersonSortCriterion> PersonSet;
PersonSet col1;
// ,
Person p1("Jay", "Chou");
Person p2("Robin", "Chou");
Person p3("Robin", "Lee");
Person p4("Bob", "Smith");
//
col1.insert(p1);
col1.insert(p2);
col1.insert(p3);
col1.insert(p4);
PersonSet::iterator pos;
// PersonSet
for (pos = col1.begin(); pos != col1.end(); ++pos)
{
cout << pos->firstname() << " " << pos->lastname() << endl;
}
cout << endl;
system("pause");
return 0;
}
여러 가지 상태의 모방 함수 가 있다
#include <iostream>
#include <list>
#include<algorithm>
using namespace std;class IntSequence
{
private:
int value; //
public:
IntSequence(int initialValue) : value(initialValue)
{
}
//
int operator()()
{
return value++;
}
};int main()
{
list<int> col1;
// 9 , col1
generate_n(back_inserter(col1),
9,
IntSequence(1));
//1 2 3 4 5 6 7 8 9
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
// col1 2 2 , 42
generate(++col1.begin(),
--col1.end(),
IntSequence(42));
//1 42 43 44 45 46 47 48 9
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
system("pause");
return 0;
}
모방 함 수 는 모두 전 달 된 값 이지 전 달 된 주소 가 아니다.따라서 알고리즘 은 매개 변수 에 따 른 모방 함수 의 상 태 를 바 꾸 지 않 습 니 다.
예 를 들 면:
IntSequence seq(1); // 1
// 1 col1 9
generate_n(back_inserter(col1), 9, seq);
// 1 col1 9
generate_n(back_inserter(col1), 9, seq);
generate 함수
#include <iostream>
#include <algorithm>
#include <array>
#include <vector>
#include <functional>
using namespace std;
int main(){
array<int,8> t1; // 100
generate(t1.begin(),t1.end(),[](){return rand()%100;}); // 5 1000
generate_n(t1.begin(),5,[](){return rand()%1000;});
for_each(t1.begin(),t1.end(),[](int i){cout<<i<<endl;});
return 0;
}
물론 상술 한 모방 함수 내부 상 태 를 변화 시 키 는 문 제 를 해결 하 는 방법 도 있다.방법 은 두 가지 가 있다.
1.인용 방식 으로 모방 함 수 를 전달한다.
2,운용 foreach()알고리즘 의 반환 값.
왜냐하면 foreach()알고리즘 은 모방 함 수 를 되 돌려 줍 니 다.즉,우 리 는 반환 값 을 통 해 모방 함수 의 상 태 를 얻 을 수 있다.
인용 방식 으로 모방 함 수 를 전달 하 다.
#include <iostream>
#include <list>
#include <algorithm>using namespace std;class IntSequence
{
private:
int value;
public:
IntSequence(int initValue) : value(initValue)
{} int operator()()
{
return value++;
}
};int main()
{
list<int> col1;
IntSequence seq(1);
//
generate_n<back_insert_iterator<list<int> >,
int, IntSequence&>(back_inserter(col1),
4,
seq);
//1 2 3 4;
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
// 42 4
generate_n(back_inserter(col1),
4,
IntSequence(42));
//1 2 3 4; 42 43 44 45
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
// , seq
// 5
// :
generate_n(back_inserter(col1),
4,
seq);
//1 2 3 4; 42 43 44 45; 5 6 7 8
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
// , 5
generate_n(back_inserter(col1),
4,
seq);
//1 2 3 4; 42 43 44 45; 5 6 7 8; 5 6 7 8
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
system("pause");
return 0;
}
운용 foreach()알고리즘 의 반환 값
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class MeanValue
{
private:
long num;
long sum;
public:
MeanValue() : num(0), sum(0)
{}
void operator() (int elem)
{
num++;
sum += elem;
} double value()
{
return static_cast<double>(sum) / static_cast<double>(num);
}
};
class Meansum
{
private:
//long num;
long sum;
public:
Meansum() : sum(0)
{}
void operator() (int elem)
{ sum += elem;
} double value()
{
return sum;
}
};
int main()
{
vector<int> col1;
for (int i = 1; i <= 8; ++i)
{
col1.push_back(i);
}
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
MeanValue mv = for_each(col1.begin(), col1.end(), MeanValue());
Meansum sum = for_each(col1.begin(), col1.end(), Meansum());
cout << "Mean Value: " << mv.value() << endl;
cout << "Mean sum: " << sum.value() << endl;
system("pause");
return 0;
}
판단 식 과 모방 함수
판단 식 은 불 형의 함수 나 모방 함 수 를 되 돌려 주 는 것 이다.STL 의 경우 불 값 을 되 돌려 주 는 모든 함수 가 합 법 적 인 판단 식 은 아니다.이것 은 다음 과 같은 의외 의 행동 을 많이 초래 할 수 있다.
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;class Nth
{
private:
int nth;
int count;
public:
Nth(int n) : nth(n), count(0)
{
}
bool operator() (int)
{
return ++count == nth;
}
};
int main()
{
list<int> col1;
for (int i = 1; i <= 9; ++i)
{
col1.push_back(i);
}
//1 2 3 4 5 6 7 8 9
for (auto t : col1) {
cout << t << " ";
}
cout << endl; list<int>::iterator pos;
pos = remove_if(col1.begin(), col1.end(), Nth(3));
col1.erase(pos, col1.end());
for (auto t : col1) {
cout << t << " ";
}
cout << endl;
system("pause");
}
함수 어댑터(함수 어댑터)
함수 어댑터:모방 함수 와 다른 모방 함수(또는 특정한 값,또는 특정한 일반 함수)를 결합 시 킬 수 있 는 모방 함수.
함수 어댑터 는 헤더 파일
먼저 몇 가지 개념,무엇이 일원 함수,이원 함수 인지 확실히 알 아 라.
1.일원 함수 매개 변수
2.이원 함수 두 개의 매개 변수
3.1 원 술어 의 매개 변 수 는 bool 형 으로 되 돌아 갑 니 다.
4.이원 서술 어 두 개의 매개 변 수 는 bool 형 으로 되 돌아 갑 니 다.
함수 어댑터 는 한 함수 대상 이 다른 유형의 함수 대상 을 나타 내 도록 하 는 특징 이다.많은 경우 에 우리 가 가지 고 있 는 함수 대상 이나 일반 함수 의 매개 변수 개수 나 반환 값 유형 은 우리 가 원 하 는 것 이 아니 기 때문에 함수 어댑터 가 우리 의 함수 에 적합 해 야 합 니 다.
C++에는 용기 어댑터,교체 기 어댑터,함수 어댑터 등 세 가지 어댑터 가 있 습 니 다.함수 어댑터 를 소개 합 니 다.
함수 어댑터 는 1 원 2 원 함수 대상 을 특 화하 고 확장 하 는 데 사용 되 며 함수 어댑터 는 주로 다음 과 같은 두 가지 종류 가 있 습 니 다.
1 귀속 기
이 종류의 어댑터 는 이원 함 수 를 일원 함수 로 맞 추 는 데 쓰 인 다
이원 함수 의 매개 변 수 를 특정한 값 에 연결 하여 이원 함수 대상 을 일원 함수 대상 으로 변환 합 니 다.
바 인 딩 기 어댑터 는 두 가지 가 있 습 니 다.bid1st bid2nd.바 인 딩 기 마다 함수 대상 과 값 을 받 습 니 다.
bind1st 는 주어진 값 을 이원 함수 대상 의 첫 번 째 실제 인삼 에 연결 합 니 다.
bind2nd 는 주어진 값 을 이원 함수 대상 의 두 번 째 실제 인삼 에 연결 합 니 다.
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>using namespace std;bool is_odd(int n)
{
return n % 2 == 1;
}int main(void)
{
int a[] = { 1, 2, 3, 4, 5 };
vector<int> v(a, a + 5); cout << count_if(v.begin(), v.end(), is_odd) << endl;
//
// bind2nd modulus 。
//bind2nd(op, value) (param) op(param, value)
cout << count_if(v.begin(), v.end(),bind2nd(modulus<int>(), 2)) << endl; //bind1st(op, value)(param) op(value, param);
// 4 , 4 < value
// 4
cout << count_if(v.begin(), v.end(),bind1st(less<int>(), 4)) << endl; // 3 , value < 3
// 3
cout << count_if(v.begin(), v.end(), bind2nd (less<int>(), 3)) << endl; // 3 , value < 3
//not1 。
//
// 3
cout << count_if(v.begin(), v.end(),not1( bind2nd (less<int>(), 3)) )<< endl;
system("pause");
return 0;
// 3 3 1 2 3
}
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.잘못 이 있 거나 완전히 고려 되 지 않 은 곳 이 있 으 면 댓 글 토론 을 환영 합 니 다.아 낌 없 는 가르침 을 바 랍 니 다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
hdu 1717 소수 화 점수 2 (수학)소수 화 점수 2 레이 는 수학 시간 에 선생님 의 말씀 을 듣 고 모든 소수 가 점수 로 표시 되 는 형식 이 라 고 말 했다. 그 는 녹 기 시 작 했 고 곧 완성 되 었 다. 그러나 그 는 또 하나의 문 제 를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.