C++
Вызываемые объекты
Поиск…
Вступление
Вызываемые объекты - это совокупность всех структур C ++, которые могут использоваться как функция. На практике это все, что вы можете передать функции C ++ 17 STL invoke () или которые могут быть использованы в конструкторе std :: function, в том числе: указатели на функции, классы с оператором (), классы с неявным преобразования, ссылки на функции, указатели на функции-члены, указатели на данные участника, lambdas. Вызываемые объекты используются во многих алгоритмах STL в качестве предиката.
замечания
Очень полезный разговор Стефана Т. Лававей ( <функциональный>: что нового и правильное использование ) ( слайды ) приводит к основанию этой документации.
Указатели функций
Указатели функций - это самый простой способ передачи функций, которые также могут использоваться в 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
Классы с оператором () (Функторы)
Каждый класс, который перегружает operator()
может использоваться как объект функции. Эти классы могут быть написаны вручную (часто называются функторами) или автоматически генерируются компилятором, написав Lambdas из C ++ 11 on.
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)
.