[CPP]std::function에 관하여
<functional> 헤더 파일에 정의된 std::function 템플릿을 이용하면
1. 함수를 가리키는 타입(함수 포인터)
2. 함수 객체
3. 람다 표현식
세개를 비롯하여 호출 가능한 모든 대상을 가리키는 타입을 생성할 수 있다.
std::function은 다형성 함수 래퍼(polymorphic function wrapper)라고도 불리며, 함수 포인터로도 사용할 수도 있고,
콜백을 구현하는 함수를 나타내는 매개변수와 사용할 수도 있다.
std::function<R(ArgTypes...)>
R은 리턴타입이고, ArgTypes는 각각을 콤마로 구분한 매개변수의 타입 목록이다.
예제 1) 함수포인터 형식
void func(int num, const string& str)
{
cout<< num <<", "<<std<<endl;
}
int main(){
std::function<void(int, const string&)> f1 = func;
f1(1, "test");
return 0;
}
이 예제에서는 auto 키워드를 사용하면 f1앞에 구체적으로 안 써도 되긴 한다. 더 간결하게 표현이 가능하다.
하지만 이렇게 하면 컴파일러는 f1의 타입이 std::function이 아니라 함수 포인터라고 판단한다.
그래서 void(*f1) (int, const string&)라고 반환해버린다.
auto f1 = func;
예제 2)
std::function 타입은 함수 포인터처럼 작동하기 때문에 표준 라이브러리 알고리즘에 인수로 전달 가능하다.
find_if() 알고리즘에 이를 적용한 예는 다음과 같다.
bool IsEven(int num)
{
return num%2 == 0;
}
int main()
{
vector<int> vec{1,2,3,4,5};
std::function<bool<int>> fcn = IsEven;
auto result = find_if(cbegin(vec),cend(vec), fcn);
if( result != cend(vec))
cout<<"첫 짝수는 : "<<*result<<endl;
else
cout<< "짝수를 찾을 수 없습니다."<<endl;
return 0;
}
이 예제들 까지를 보면 굳이 std::function을 사용할 필요가 없다는 생각이 들 수도 있다.
std::function의 진가는 콜백을 클래스의 멤버 변수에 저장해야 할 때와 함수 포인터를 매개변수로 받아야 할 때도 유용하다.
예제 3) 함수포인터 , 람다 표현식
void process(const vector<int>& vec, function<void(int)> f)
{
for(auto& i : vec)
{
f(i);
}
}
void print(int num)
{
cout<< num << " ";
}
int main()
{
vector<int> vec{0,1,2,3,4,5};
//print를 함수포인터로 전달해서 호출
process(vec,print);
cout<<endl;
//람다 표현식을 std::function 매개변수의 값으로 지정하는 예
// std::function의 진가!
// 일반 함수 포인터로는 이렇게 처리할 수 없다.
int sum = 0;
process(vec,[&sum](int num) {sum +=num;});
cout<<"sum = "<< sum <<endl;
return 0;
}
출력 결과
0 1 2 3 4 5
sum = 15
콜백 매개변수로 std::function을 사용하지 않고, 함수 템플릿으로 만들어도 된다.
template<typename F>
void processTemplate(const vector<int>& vec, F f)
{
for(auto& i:vec)
{
f(i);
}
}
이렇게 정의한 함수 템플릿은 비템플릿 process() 함수와 기능이 같다.
processTemplate()는 일반 함수 포인터와 람다 표현식을 모두 받을 수 있다.
가능하면 함수객체보다는 람다 표현식을 사용하기 바란다. 람다 표현식이 코드를 작성하기 쉬울뿐만 아니라 읽거나 이해하기 쉽다.
이전에 정리한 람다식 관련
https://hyo-ue4study.tistory.com/324
참고서적 :
http://www.yes24.com/Product/Goods/77669043