r/cpp_questions • u/CommandShot1398 • 5d ago
OPEN How does std::bind differentiate between arguments and pointer to an object?
Hi everyone,
I have difficulties understanding something:
class HttpServer {
public:
HttpServer(std::string_view address, uint16_t port):ioc{1},endpoint{boost::asio::ip::make_address(address)},
acceptor{ioc,{endpoint,port}} {
};
~HttpServer()=default;
void handle_request() {
for (;;) {
tcp::socket socket{ioc};
// Block until we get a connection
acceptor.accept(socket);
std::cout<<"connection accepted"<<std::endl;
std::thread{std::bind(
&HttpServer::do_session,this,
std::move(socket))}.detach();
}
}
void do_session(tcp::socket& socket) {
//handle request
}
private:
const boost::asio::ip::address endpoint;
uint16_t port;
boost::asio::io_context ioc;
tcp::acceptor acceptor;
};
In this piece of code, how does std::bind understand that it should infer this as a pointer to the object which own the function pointer (I'm not even sure if I stated it correctly)?
according to chatgpt
std::bind( function, argument1, argument2, argument3 )
is a template that takes a pointer to the function that it should return the wrapper for, along with the arguments and their placeholders. What I don't understand is how it differentiates between the "this" pointer and an argument? How does it know it should take the non-static member function and dereference it based on the address (or reference) of the object that owns it, rather than just using "this" pointer as another argument?
3
u/kiner_shah 5d ago
From cppreference:
As described in Callable, when invoking a pointer to non-static member function or pointer to non-static data member, the first argument has to be a reference or pointer (including, possibly, smart pointer such as std::shared_ptr and std::unique_ptr) to an object whose member will be accessed.
1
u/CommandShot1398 5d ago
I understand this; what I don't understand is the mechanism behind it. How can it differentiate? Does "this" pointer have a very specific type beyond the object type?? How does it know it is not another object of the same type? To my knowledge, it can't be a simple overload or template.
2
2
2
u/Beginning_Block5406 5d ago
and check itanium abi for understanding why member function pointer has specific
1
0
u/MoTTs_ 5d ago edited 5d ago
What I don't understand is how it differentiates between the "this" pointer and an argument?
It actually doesn't have to.
I think the missing piece of information is that, every object's "this" is ultimately implemented as an ordinary parameter/argument. Which means that when you write a member function signature, such as...
class HttpServer {
...
void do_session(tcp::socket& socket) {
...this member function appears to us to take just one parameter, because that's what the source code shows. But in truth, the compiler is implicitly inserting an extra parameter for you. From the compiler's perspective, your member function is actually this...
class HttpServer {
...
void do_session(HttpServer* this, tcp::socket& socket) {
And so in bind, it doesn't actually need to differentiate this from other arguments, because this really is... just another argument.
1
u/amoskovsky 5d ago
While under the hood `this` indeed is implemented as the first param of a method, this does not help std::bind, because it has to invoke the method using C++ syntax, but there is no such syntax as `method_ptr(object_ptr, ...)` so it has to do template specialization as mentioned by others and use a different syntax `object_ptr->*method_ptr(...)`.
PS. Starting with C++17 std::invoke() that actually implements this dispatch is available to devs for direct use.
10
u/Dan13l_N 5d ago
This is likely done by template specialization. If the first argument of
std::bindis a non-static member function, the second argument must be a pointer to object you'll call the function on.