프로그래밍 언어/C++

C ++ functor와 그 용도

Rateye 2021. 7. 13. 10:25
728x90
반응형
질문 : C ++ functor와 그 용도는 무엇입니까?

C ++의 functor에 대해 계속 많이 듣습니다. 누군가 나에게 그들이 무엇인지, 어떤 경우에 유용 할 것인지에 대한 개요를 줄 수 있습니까?

답변

functor는 operator ()를 정의하는 클래스 일뿐입니다. 이를 통해 함수와 "같이 보이는"객체를 만들 수 있습니다.

// this is a functor
struct add_x {
  add_x(int val) : x(val) {}  // Constructor
  int operator()(int y) const { return x + y; }

private:
  int x;
};

// Now you can use it like this:
add_x add42(42); // create an instance of the functor class
int i = add42(8); // and "call" it
assert(i == 50); // and it added 42 to its argument

std::vector<int> in; // assume this contains a bunch of values)
std::vector<int> out(in.size());
// Pass a functor to std::transform, which calls the functor on every element 
// in the input sequence, and stores the result to the output sequence
std::transform(in.begin(), in.end(), out.begin(), add_x(1)); 
assert(out[i] == in[i] + 1); // for all i

펑터에 대한 몇 가지 좋은 점이 있습니다. 하나는 일반 함수와 달리 상태를 포함 할 수 있다는 것입니다. 위의 예제는 당신이 제공하는 것에 42를 더하는 함수를 생성합니다. 하지만 그 값 42는 하드 코딩되지 않았고, functor 인스턴스를 만들 때 생성자 인자로 지정되었습니다. 다른 값으로 생성자를 호출하여 27을 더한 또 다른 가산기를 만들 수 있습니다. 이를 통해 멋지게 사용자 정의 할 수 있습니다.

마지막 줄에서 볼 수 있듯이 std :: transform 또는 기타 표준 라이브러리 알고리즘과 같은 다른 함수에 대한 인수로 functor를 종종 전달합니다. 위에서 말했듯이 펑 터는 상태를 포함하기 때문에 "사용자 정의"할 수 있다는 점을 제외하면 일반 함수 포인터로도 똑같이 할 수 있습니다 (함수 포인터를 사용하려면 함수를 작성해야합니다). 인수에 정확히 1을 추가했습니다. functor는 일반적이며 초기화 한 모든 항목을 추가합니다.) 그리고 잠재적으로 더 효율적입니다. 위의 예에서 컴파일러는 std::transform 이 호출해야하는 함수를 정확히 알고 있습니다. add_x::operator() 호출해야합니다. 즉, 해당 함수 호출을 인라인 할 수 있습니다. 그리고 그것은 벡터의 각 값에 대해 수동으로 함수를 호출 한 것처럼 효율적입니다.

대신 함수 포인터를 전달했다면 컴파일러는 자신이 가리키는 함수를 즉시 알 수 없으므로 상당히 복잡한 전역 최적화를 수행하지 않는 한 런타임에 포인터를 역 참조한 다음 호출해야합니다.

출처 : https://stackoverflow.com/questions/356950/what-are-c-functors-and-their-uses
728x90
반응형