c++stdbindcpprest-sdk

C++ I don't know what it means to use "this" and "std::placeholders::_1" when using the callback function


I am trying to make a server by looking at the sample code of cpprestSDK. But I don't know why I bind in the sample code.

Below is the sample code.

stdafx.h

class Handler{
public:
    Handler() {};
    Handler(utility::string_t url);

    pplx::task<void> open() { return m_listener.open(); }
    pplx::task<void> close() { return m_listener.close(); }

private:
    void handle_get(http_request request);
    void handle_put(http_request request);
    void handle_post(http_request request);
    void handle_del(http_request request);
};

hander.cpp

  
#include "stdafx.hpp"

Handler::Handler(utility::string_t url) : m_listener(url)
{

    m_listener.support(methods::GET, std::bind(&Handler::handle_get, this, std::placeholders::_1));
    m_listener.support(methods::PUT, std::bind(&Handler::handle_put, this, std::placeholders::_1));
    m_listener.support(methods::POST, std::bind(&Handler::handle_post, this, std::placeholders::_1));
    m_listener.support(methods::DEL, std::bind(&Handler::handle_del, this, std::placeholders::_1));
}

Looking at the reference for support, it is defined as follows.

void support (const http::method &method, const std::function< void(http_request)> &handler)

I thought I could define it like this:

m_listener.support(methods::GET, &Handler::handle_get);

But it failed.

Can you tell me why I use "this" and "std::placeholders::_1" when doing a bind?

sample code : https://learn.microsoft.com/ko-kr/archive/blogs/christophep/write-your-own-rest-web-server-using-c-using-cpp-rest-sdk-casablanca

cpprestSDK listener reference : https://microsoft.github.io/cpprestsdk/classweb_1_1http_1_1experimental_1_1listener_1_1http__listener.html


Solution

  • The member function

    void support (const http::method &method,
                  const std::function< void(http_request)> &handler)
    

    expects handler to be a callable which has

    A plain function void handle(http_request) would match this required signature.

    If you want to register a (non-static) member function this is also possible but you have to provide the object as well (as non-static member functions may not be called without object).

    The std::bind(&Handler::handle_get, this, std::placeholders::_1) acts as (a kind of) adapter to fit your member function (with this as bound object) into that requirement.

    The std::placeholders::_1 denotes, where to bind the argument (of type http_request) into the wrapped member function call.

    A simpler way would be to use a lambda as adapter (instead of the bind):

    m_listener.support(methods::GET, [this](http_request http_req) { this->handle_get(http_req); });
    

    or even:

    m_listener.support(methods::GET, [this](http_request http_req) { handle_get(http_req); });
    

    Further readings: