본문 바로가기
프로그래밍/C++

C++ Functor(함수 객체)

by comflex 2023. 2. 17.
728x90
반응형

C++에서 Functor(함수 객체)는 일반적인 함수 포인터와 달리 객체를 사용하여 함수를 나타냅니다. Functor를 사용하면 C++의 객체 지향 기능과 제네릭 프로그래밍 기능을 모두 활용할 수 있습니다. 이 글에서는 C++에서 Functor가 무엇이고 어떻게 사용하는지에 대해 자세히 알아보겠습니다.

Functor란 무엇인가?

Functor는 일반적으로 "함수 객체"라고도 불리며, 함수처럼 호출할 수 있는 객체입니다. 일반적인 함수와 달리, Functor는 상태(state)를 유지할 수 있으므로, 호출될 때마다 다른 결과를 생성할 수 있습니다.

Functor는 C++에서 특별한 형태의 객체입니다. 이 객체는 일반적으로 함수 호출 연산자(operator())를 정의하여 함수 호출을 수행합니다. 따라서 Functor 객체를 함수처럼 호출할 수 있습니다.

class MyFunctor {
public:
    void operator()() const {
        std::cout << "Hello, world!" << std::endl;
    }
};

int main() {
    MyFunctor f;
    f(); // Hello, world!
    return 0;
}

위 예시에서는 MyFunctor 클래스를 정의하여 operator() 함수 호출 연산자를 정의합니다. 이 연산자는 "Hello, world!"를 출력합니다. main 함수에서는 MyFunctor 객체 f를 만들고 호출합니다.

반응형

Functor 사용 예시

Functor를 사용하여 STL의 다양한 알고리즘을 수행할 수 있습니다. 예를 들어, 다음은 sort 알고리즘을 사용하여 벡터를 오름차순으로 정렬하는 방법입니다.

 

#include <iostream>
#include <vector>
#include <algorithm>

class MyFunctor {
public:
    bool operator()(int a, int b) const {
        return a < b;
    }
};

int main() {
    std::vector<int> v {5, 2, 1, 4, 3};
    std::sort(v.begin(), v.end(), MyFunctor());
    for (auto i : v) {
        std::cout << i << " ";
    }
    return 0;
}

위 예시에서는 MyFunctor 클래스를 작성하여 sort 알고리즘에서 사용됩니다. MyFunctor 클래스는 두 개의 입력 값에 대해 첫 번째 값이 더 작으면 true를 반환합니다. sort 알고리즘은 MyFunctor 객체를 사용하여 벡터를 정렬합니다. main 함수에서는 정렬된 벡터를 출력합니다.

Functor를 사용하여 다양한 알고리즘에서도 재사용이 가능합니다. 다음은 for_each 알고리즘을 사용하여 벡터를 출력하는 방법입니다.

 

#include <iostream>
#include <vector>
#include <algorithm>

class MyFunctor {
public:
    void operator()(int i) const {
        std::cout << i << " ";
    }
};

int main() {
    std::vector<int> v {1, 2, 3, 4, 5};
    std::for_each(v.begin(), v.end(), MyFunctor());
    return 0;

위 예시에서는 MyFunctor 클래스를 작성하여 for_each 알고리즘에서 사용됩니다. MyFunctor 클래스는 operator() 함수 호출 연산자를 정의하며, 하나의 정수를 인자로 받아서 출력합니다. for_each 알고리즘은 벡터를 순회하면서 각 요소에 대해 MyFunctor 객체를 호출합니다.

Functor를 사용한 제네릭 프로그래밍

Functor는 제네릭 프로그래밍에 사용될 수 있는 매우 유용한 기술입니다. 제네릭 프로그래밍에서는 템플릿을 사용하여 모든 데이터 유형에 대해 동일한 코드를 작성할 수 있습니다. Functor를 사용하면 템플릿 함수에 전달할 수 있는 일반적인 함수 인터페이스를 제공할 수 있습니다.

예를 들어, 다음은 제네릭 템플릿 함수를 작성하는 방법입니다.

 

#include <iostream>
#include <vector>

template<typename T, typename F>
void apply(std::vector<T>& v, F f) {
    for (auto& x : v) {
        f(x);
    }
}

class MyFunctor {
public:
    void operator()(int i) const {
        std::cout << i << " ";
    }
};

int main() {
    std::vector<int> v {1, 2, 3, 4, 5};
    apply(v, MyFunctor());
    return 0;
}

위 예시에서는 apply 템플릿 함수를 작성하여 벡터의 모든 요소에 대해 MyFunctor 객체를 적용합니다. apply 함수는 MyFunctor 객체를 전달하고, MyFunctor 객체는 하나의 정수를 출력합니다.

Functor와 람다 표현식

C++11부터는 람다 표현식이 도입되어 Functor를 작성하는 방법이 매우 간편해졌습니다. 람다 표현식은 익명 함수를 작성하는 데 사용됩니다.
 
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v {5, 2, 1, 4, 3};
    std::sort(v.begin(), v.end(), [](int a, int b) { return a < b});
    for (auto i : v) {
    	std::cout << i << " ";
    }
	return 0;
}

위 예시에서는 sort 함수에 람다 표현식을 사용하여 벡터를 정렬합니다. 람다 표현식은 대괄호([])로 시작하며, 함수 인자를 콤마로 구분하여 괄호 안에 지정합니다. 이어지는 화살표(->)는 반환값의 유형을 지정합니다. 반환 값이 없는 경우에는 void를 사용할 수 있습니다. 중괄호 안에는 함수 몸체가 작성됩니다.

람다 표현식은 Functor와 비슷한 역할을 수행합니다. 람다 표현식을 사용하여 더욱 간단하고 효율적인 코드를 작성할 수 있습니다.

 

2023.01.04 - [프로그래밍/C++] - C++ std::sort

 

C++ std::sort

std::sort는 C++의 STL(Standard Template Library)에서 제공하는 정렬 알고리즘입니다. std::sort 함수는 입력받은 시작 위치와 끝 위치 사이의 요소들을 정렬할 수 있습니다. 정렬은 오름차순으로 진행되며,

com-flex.tistory.com

2022.02.19 - [프로그래밍/C++] - C++ std::begin, std::end, iterator

 

C++ std::begin, std::end, iterator

std::begin, std::end, iterator 데이터 타입에 맞는 iterator를 리턴한다. 목차 begin end begin 처음 원소를 가르키는 iterator를 리턴한다. end 마지막 원소 다음을 가리키는 iterator를 리턴한다. 코드 #include #includ

com-flex.tistory.com

2023.02.21 - [프로그래밍/C++] - C++ 쓰레드(thread)

728x90
반응형

'프로그래밍 > C++' 카테고리의 다른 글

C++ 쓰레드(thread)  (2) 2023.02.21
C++ transform  (0) 2023.02.18
C++ std::sort  (2) 2023.01.04
C++ enum 열거형  (1) 2023.01.04
C++ std::begin, std::end, iterator  (0) 2022.02.19