수색…
소개
호출 가능한 객체는 함수로 사용할 수있는 모든 C ++ 구조체의 모음입니다. 실제로 이것은 C ++ 17 STL 함수 invoke ()에 전달할 수 있거나 std :: function의 생성자에서 사용할 수있는 모든 것입니다. 함수 포인터, 연산자 ()가있는 클래스, 암시 적 클래스 변환, 함수 참조, 멤버 함수에 대한 포인터, 멤버 데이터에 대한 포인터, lambdas. 호출 가능한 개체는 많은 STL 알고리즘에서 조건 자로 사용됩니다.
비고
Stephan T. Lavavej ( <기능> : 새로운 기능, 올바른 사용법 ) ( 슬라이드 )의 매우 유용한 이야기는이 문서의 기반으로 연결됩니다.
함수 포인터
함수 포인터는 C 에서 사용할 수있는 함수를 전달하는 가장 기본적인 방법입니다 (자세한 내용은 C 설명서 참조).
호출 가능한 객체의 목적을 위해 함수 포인터는 다음과 같이 정의 될 수 있습니다.
typedef returnType(*name)(arguments); // All
using name = returnType(*)(arguments); // <= C++11
using name = std::add_pointer<returnType(arguments)>::type; // <= C++11
using name = std::add_pointer_t<returnType(arguments)>; // <= C++14
우리 자신의 벡터 정렬을 작성하기 위해 함수 포인터를 사용한다면 다음과 같이 보일 것입니다 :
using LessThanFunctionPtr = std::add_pointer_t<bool(int, int)>;
void sortVectorInt(std::vector<int>&v, LessThanFunctionPtr lessThan) {
if (v.size() < 2)
return;
if (v.size() == 2) {
if (!lessThan(v.front(), v.back())) // Invoke the function pointer
std::swap(v.front(), v.back());
return;
}
std::sort(v, lessThan);
}
bool lessThanInt(int lhs, int rhs) { return lhs < rhs; }
sortVectorInt(vectorOfInt, lessThanInt); // Passes the pointer to a free function
struct GreaterThanInt {
static bool cmp(int lhs, int rhs) { return lhs > rhs; }
};
sortVectorInt(vectorOfInt, &GreaterThanInt::cmp); // Passes the pointer to a static member function
또는 다음과 같은 방법으로 함수 포인터를 호출 할 수 있습니다.
-
(*lessThan)(v.front(), v.back()) // All
-
std::invoke(lessThan, v.front(), v.back()) // <= C++17
연산자가있는 클래스 (Functor)
operator()
를 오버로드하는 모든 클래스는 함수 객체로 사용할 수 있습니다. 이러한 클래스는 손으로 (펑터라고도 함) 작성하거나 C ++ 11에서 Lambdas 를 작성하여 컴파일러에서 자동으로 생성 할 수 있습니다.
struct Person {
std::string name;
unsigned int age;
};
// Functor which find a person by name
struct FindPersonByName {
FindPersonByName(const std::string &name) : _name(name) {}
// Overloaded method which will get called
bool operator()(const Person &person) const {
return person.name == _name;
}
private:
std::string _name;
};
std::vector<Person> v; // Assume this contains data
std::vector<Person>::iterator iFind =
std::find_if(v.begin(), v.end(), FindPersonByName("Foobar"));
// ...
펑터는 자신 만의 정체성을 가지고 있기 때문에 typedef에 넣을 수 없으며 템플릿 인수를 통해 받아 들여야합니다. std::find_if
의 정의는 다음과 같습니다.
template<typename Iterator, typename Predicate>
Iterator find_if(Iterator begin, Iterator end, Predicate &predicate) {
for (Iterator i = begin, i != end, ++i)
if (predicate(*i))
return i;
return end;
}
C ++ 17에서, 술어의 호출은 invoke : std::invoke(predicate, *i)
사용하여 수행 할 수 있습니다.