3

I created an vectorstd::function with a specified function type, as follows.

std::vector<std::function<void(int)>> v;

The type of the elements in this vector should be void(int), but I can push other function types into it, like:

    v.emplace_back([](int x) -> int {
        return 1;
    });

The complete codes are:

int main()
{
    std::vector<std::function<void(int)>> v;
    v.emplace_back([](int x) -> int {
        return 1;
    });
}

And it is compiled successfully, why compiler did not complain about this type error?

Even if the compiler reports an error only when this element is called explicitly in the code, why is it not reported when it is not called explicitly?

Junhui Zhu
  • 93
  • 5

1 Answers1

2

In std::function<R(Ts...)>, you can store any callable g as long as as it can be called with Ts objects and returns R-like object.

Meaning g does not have to have the same arguments, only those implicitly-convertible from Ts. Regarding the return value

  • if R is void, g can return anything and it will be ignored.
  • if not, g must return something implicitly convertible to R.
Quimby
  • 17,735
  • 4
  • 35
  • 55
  • Thank you. So the compiler is able to pass here because of the fact that the return value has been ignored, right? – Junhui Zhu Aug 26 '22 at 06:52
  • @JunhuiZhu Yes, exactly. And the argument of the lambda can be anything that can be implicitly converted from `int`, i.e. what makes `your_lambda(int(5));` valid. – Quimby Aug 26 '22 at 07:11
  • is there a way to restrict `std::function` to accept only functions without return value? – The Dreams Wind Aug 26 '22 at 07:25
  • @TheDreamsWind No and this is intentional. In general, you cannot restrict type's constructors without changing them and `std::function` cannot be changed by an user of course. – Quimby Aug 26 '22 at 07:27