Sök…


Introduktion

Callable objekt är samlingen av alla C ++ strukturer som kan användas som en funktion. I praktiken är detta allt du kan skicka till C ++ 17 STL-funktionen åberopa () eller som kan användas i konstruktören av std :: -funktionen, detta inkluderar: Funktionspekare, klasser med operatör (), klasser med implicit konverteringar, Hänvisningar till funktioner, Pekare till medlemsfunktioner, Pekare till medlemsdata, lambdas. De kallbara objekten används i många STL-algoritmer som predikat.

Anmärkningar

Ett mycket användbart föredrag av Stephan T. Lavavej ( <funktionell>: Nyheter och korrekt användning ) ( Slides ) leder till basen i denna dokumentation.

Funktionspekare

Funktionspekare är det mest grundläggande sättet att överföra funktioner som också kan användas i C. (Se C-dokumentationen för mer information).

I syfte att räkna ut objekt kan en funktionspekare definieras som:

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

Om vi skulle använda en funktionspekare för att skriva vår egen vektorsort, skulle det se ut som:

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

Alternativt kunde vi ha åberopat funktionspekaren på något av följande sätt:

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

Lektioner med operatör () (Functors)

Varje klass som överbelaster operator() kan användas som ett funktionsobjekt. Dessa klasser kan skrivas för hand (ofta kallad funktorer) eller automatiskt genereras av kompilatorn genom att skriva Lambdas från C ++ 11 på.

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

Eftersom funktorer har sin egen identitet kan de inte läggas in i en typedef och dessa måste accepteras via mallargument. Definitionen av std::find_if kan se ut:

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

Från C ++ 17 kan predikatets anrop göras med invoke: std::invoke(predicate, *i) .



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow