std::bind auf Memberfunktion mit Parametern



  • Hallo,
    ich versuche eine std::function auf eine Memberfunktion mit Parametern zu erzeugen. Hier der Code:

    #include <iostream>
    #include <functional>
    
    struct Foo
    {
        void f0()               { std::cout << "f0\n"; }
        void f1(int a)          { std::cout << "f1(" << a << ")\n"; }
    };
    
    int main(int argc, char* argv[])
    {
        Foo foo;
    
        // das funktioniert
        std::function<void()> fn0 = std::bind(&Foo::f0, foo);
        fn0();
        // das geht nicht:
        std::function<void(int)> fn1 = std::bind(&Foo::f1, foo);
        fn1(2);
    }
    

    Die Fehlermeldung lautet:

    foo.cpp: In function ‘int main(int, char**)’:
    foo.cpp:17:59: error: conversion from ‘std::_Bind_helper<false, void (Foo::)(int), Foo&>::type {aka std::_Bind<std::_Mem_fn<void (Foo::)(int)>(Foo)>}’ to non-scalar type ‘std::function<void(int)>’ requested
    std::function<void(int)> fn1 = std::bind(&Foo::f1, foo);

    Ich hätte erwartet, dass ich eine std::function mit einem Parameter bekommen. Wie kann ich ein solches std::function-Objekt erzeugen?



  • std::function<void (int)> fn1 = std::bind(&Foo::f1, foo, std::placeholders::_1);
    


  • Benutze Lambda statt std::bind. Du brauchst hier auch kein std::function.

    auto fn1 = [=](int a) { foo.f1(a); };
    fn1(2);
    

    Wenn du foo nicht kopieren möchtest, benutze [&] statt [=]. Bei bind müsstest du std::ref(foo)verwenden.



  • richtig, mit dem placeholder geht es 👍🏻

    Mir gefällt das mit dem std::bind besser als mit lambda.

    Statt std::ref kann ich auch einen Zeiger auf das Objekt übergeben. Dann wird auch nicht mehr kopiert.



  • @tntnet sagte in std::bind auf Memberfunktion mit Parametern:

    Mir gefällt das mit dem std::bind besser als mit lambda.

    Ja wie toll bind ist sieht man daran wie sehr du keine Probleme damit hast. Und wie wenig man es nicht gut lesen kann. Und...
    Überwinde dich, und nimm Lambdas!


Log in to reply