Frage

Was ist los mit dem folgenden kleinen Programm, das eine Funktion Objekt passiert?

#include <iostream>
#include <functional>

void foo(const std::unary_function<const std::string&, void>& fct) {
  const std::string str = "test";
  fct(str); // error
}

class MyFct : public std::unary_function<const std::string&, void> {
public:
  void operator()(const std::string& str) const {
    std::cout << str << std::endl;
  }
};

int main(int argc, char** argv){
  MyFct f;
  foo(f);
  return 0;
}

Ich erhalte die folgenden Fehler in Zeile 6:

 no match for call to 
`(const std::unary_function<const std::string&, void>) (const std::string&)'
War es hilfreich?

Lösung

Ein häufiger Fehler. unary_function und binary_function sind nur zwei Strukturen, die typedefs

hinzufügen
argument_type
result_type

bzw.

first_argument_type
second_argument_type
result_type

Nicht mehr. Sie sind für die Bequemlichkeit der Schöpfer der Funktion Objekttypen, so dass sie nicht über jene selbst zu tun. Aber sie verhalten sich nicht polymorph. Was Sie wollen, ist Funktion Objekt-Wrapper. boost::function in den Sinn kommt:

void foo(boost::function<void(const std::string&)> const& fct) {
  const std::string str = "test";
  fct(str); // no error anymore
}

Oder machen Sie es sich um eine Vorlage

template<typename FunctionObject>
void foo(FunctionObject const& fct) {
  const std::string str = "test";
  fct(str); // no error anymore
}

Sie können es von Wert nehmen und dann die Kopie von foo zurück, wenn es verwenden, um es irgendeine Reihenfolge anzuwenden. Was die Funktion Objekt erlauben würde, einige Zustandsvariablen unter seinen Mitgliedern zu aktualisieren. for_each ist ein Beispiel, das es so tut. Im Allgemeinen wie auch immer, würde ich sie von Wert annehmen, weil sie in der Regel klein sind und sie ermöglichen das Kopieren von mehr Flexibilität. Also ich tun

template<typename FunctionObject>
void foo(FunctionObject fct) {
  const std::string str = "test";
  fct(str); // no error anymore
}

Sie erhalten dann eine Kopie von fct nehmen können und es irgendwo speichern und fct des Betreibers () kann nicht const sein und einige Mitglieder aktualisieren (die Teil des ganzen Punkt von operator() ist). Denken Sie daran, wenn Sie eine Funktion Objekt durch konstante Referenz nehmen, können Sie im Allgemeinen nicht kopieren, weil der Benutzer eine Funktion übergeben konnte. Kopieren sie dann versuchen, lokal deklarieren eine Funktion statt einer lokalen Funktionszeiger. Jedoch durch-Wert zu übernehmen einen Funktionszeiger stattdessen akzeptieren, wenn eine Funktion übergeben wurde, was sicher kopiert werden kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top