Why can I std::bind successfully with the wrong parameters?
Asked Answered
H

2

7
#include <iostream>
#include <functional>

using callback = std::function<void(int, void*)>;

void AddCallback(callback cb) {}

void foo(int i) {}

int main() {
  auto f = std::bind(&foo, std::placeholders::_1);
  AddCallback(f);
}

I tried the code with g++ 9.3.0 and clang++ 10.0.0, they both compiled ends no errors.

Is the type of bind result and callback the same type? One is std::function<void(int, void*)>, the other is something equal to std::function<void(int)>? Why can I call AddCallback() with different types?

Hamnet answered 3/7, 2020 at 8:53 Comment(0)
O
3

It seems you can pass more arguments to the result of bind than necessary, and they will be silently ignored.

If some of the arguments that are supplied in the call to [the result of bind] are not matched by any placeholders ..., the unused arguments are evaluated and discarded.

cppreference

Osmium answered 3/7, 2020 at 8:59 Comment(3)
Is the type of bind result and callback the same type? why can I call AddCallback() with different types? One is std::function<void(int, void*)>, the other is something equal to std::function<void(int)>?Hamnet
@Hamnet Because std::function can be constructed from any callable that you can call with the specified arguments. If you can call the result of std::bind using the arguments of the specified types, it can be converted to a std::function.Sultana
The result of std::bind is a type with a templated operator(). It isn't an instantiation of std::function, rather std::function<void(int, void*)> has a converting constructor that accepts the binder typeSousa
M
0

it's not your AddCallback() whose accepting differnt type but it's type deduction whose creating confusing;

for example try to use

std::function<void(int)> f = std::bind(&foo, std::placeholders::_1);

or Addcallback function we will give you error

Error (active) E0312 no suitable user-defined conversion from "std::function<void (int)>" to "callback" exists

Muskeg answered 3/7, 2020 at 9:25 Comment(2)
The problem is that result of std::bind call is not std::function, it's an unspecified type that can be converted to std::function. If you changed type of f to std::function<void(int, void*)>, it would compile perfectly.Schizont
That's true. That type of std::bind is unspecified but his question is "Why can I call AddCallback() with different types?"Muskeg

© 2022 - 2024 — McMap. All rights reserved.