Zoeken…


Invoering

Oproepbare objecten zijn de verzameling van alle C ++ -structuren die als functie kunnen worden gebruikt. In de praktijk zijn dit allemaal dingen die u kunt doorgeven aan de functie C ++ 17 STL invoke () of die kunnen worden gebruikt in de constructor van std :: function, dit omvat: Functie-aanwijzers, Klassen met operator (), Klassen met impliciete conversies, verwijzingen naar functies, verwijzingen naar lidfuncties, verwijzingen naar lidgegevens, lambdas. De opvraagbare objecten worden als predicaat in veel STL-algoritmen gebruikt.

Opmerkingen

Een zeer nuttige lezing door Stephan T. Lavavej ( <functioneel>: Wat is er nieuw en correct gebruik ) ( Slides ) leidt naar de basis van deze documentatie.

Functie wijzers

Functie-aanwijzers zijn de meest basale manier om functies door te geven, die ook in C kunnen worden gebruikt (zie de C-documentatie voor meer informatie).

Ten behoeve van opvraagbare objecten kan een functiepointer worden gedefinieerd als:

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

Als we een functie-aanwijzer zouden gebruiken om onze eigen vectorsoort te schrijven, zou het er als volgt uitzien:

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

Als alternatief hadden we de functiepointer op een van de volgende manieren kunnen gebruiken:

  • (*lessThan)(v.front(), v.back()) // All
  • std::invoke(lessThan, v.front(), v.back()) // <= C++17

Klassen met operator () (Functors)

Elke klasse die de operator() overbelast operator() kan worden gebruikt als een functieobject. Deze klassen kunnen met de hand worden geschreven (vaak aangeduid als functors) of automatisch worden gegenereerd door de compiler door Lambdas vanaf C ++ 11 te schrijven.

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"));
// ...

Omdat functors hun eigen identiteit hebben, kunnen ze niet in een typedef worden geplaatst en moeten deze worden geaccepteerd via een sjabloonargument. De definitie van std::find_if kan er als volgt uitzien:

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;
}

Vanaf C ++ 17 kan het aanroepen van het predicaat worden gedaan met invoke: std::invoke(predicate, *i) .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow