[C++] boost::bind vs lamdba

Pagina: 1
Acties:

Acties:
  • +1 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
C++:
1
2
3
4
5
6
7
8
9
10
11
12
void connection::handle_timer();

    ...

    timer_.async_wait(boost::bind(&connection::handle_timer, shared_from_this())); // 1

    timer_.async_wait([this](const boost::system::error_code& e) // 2
    {
        socket_.close();
    });

    ...


AFAIK zijn beide statements equivalent, maar waarom zie ik in de bind variant de error_code parameter nergens terug?
De lambda lijkt mij eenvoudiger maar ik begrijp niet hoe de boost:bind variant precies werkt.

http://www.boost.org/doc/...ine_timer/async_wait.html

  • Rotterdammertje
  • Registratie: Juni 2002
  • Laatst online: 28-03-2023
shared_from_this() geeft een pointer terug naar het huidige object. boost::bind knoopt deze vervolgens aan &connection::handle_timer, zodat het resultaat een pointer naar de object method this->handle_timer is. Deze method heeft een system::error_code parameter.

In beide gevallen zal timer_.async_wait dus een pointer naar een functie met als parameter een system::error_code doorkrijgen. In het eerste geval is dit de handle_timer method van je connection object; in het tweede geval je lambda.

Zie ook: http://www.boost.org/doc/...ind_with_pointers_to_memb

main = putStr (q ++ show q); q = "main = putStr (q ++ show q); q = "


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Rotterdammertje schreef op donderdag 22 december 2016 @ 11:05:
shared_from_this() geeft een pointer terug naar het huidige object. boost::bind knoopt deze vervolgens aan &connection::handle_timer, zodat het resultaat een pointer naar de object method this->handle_timer is. Deze method heeft een system::error_code parameter.
Zoals je op regel 1 kunt zien heeft handle_timer() geen parameters.. vandaar mijn verwarring en vraag.

  • ahprins
  • Registratie: Mei 2015
  • Laatst online: 03-09 10:55
Is dit min of meer dezelfde vraag als http://stackoverflow.com/...it-handler-signature?rq=1 ?

Het error code argument dat door boost async_wait wordt doorgegeven wordt "gewoon genegeerd" door het bind object. Net zoals bijvoorbeeld:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <boost/bind.hpp>

double bar( double x )
{
   return 123456.789 * x;
}


int main( int argc, char* argv[] )
{
   double baz = 0.001;
   std::cerr << " Boost::Bind( bar )" << boost::bind( bar, baz )( 1., 2.0, 3.0 ) << std::endl;
   
   return 0;
}


De argumenten 1., 2.0, 3.0 op regel 13 worden gewoon genegeerd.

[ Voor 67% gewijzigd door ahprins op 22-12-2016 12:25 . Reden: Voorbeeld code toegevoegd ]


  • expor
  • Registratie: Juni 2005
  • Laatst online: 01-10 22:53
Omdat boost::bind argumenten verwacht zoals de functie die jij meegeeft ze wil hebben. Als jouw locale handle_timer geen argumenten heeft (en dus niet heeft zoals te zien) dan vind bind() dat prima. Als de callback wel een parameter zou meegeven dan wordt deze simpelweg genegeerd. Op die manier kan je dus zelf alleen relevante parameters doorgeven naar je callback.

Als je dus wel de parameter wil afhandelen (error code in dit geval) krijg je dit:
code:
1
timer_.async_wait(boost::bind(&connection::handle_timer, shared_from_this(), _1)); // 1

_1 geeft hierbij aan dat het eerste argument dat de callback als parameter heeft wordt doorgegeven. Als de functie meerdere argumenten heeft kan je dus met behulp van _n aangeven welk argument je wil hebben.

In de lambda maak je direct een locale functie die dus wel moet voldoen aan de callback van async_wait.

[ Voor 51% gewijzigd door expor op 22-12-2016 13:39 ]

AMD 5800X3D | 16gb DDR 4 @ 3800/14 | 4070 Ti | 1TB Samsung Evo 970, 1TB Samsung Evo 860, 512MB Crucial