I want to store a function inside a std::function
. I don't care about the return value when calling this stored function, so the std::function
just returns void
.
Is there any undefined behavior when the stored function gets called?
Take the following example as a reference, where the function is a lambda returning an int
(Link to run):
#include <iostream>
#include <functional>
std::function<void(void)> f;
int main()
{
f = []() -> int { std::cout << "Returning int\n"; return 0; };
f(); // Is this UB in any way?
return 0;
}
The question applies not only to lambdas, but to any callable, such as member functions, free functions, etc.
Ignoring the return result is explicitly allowed.
You are using the template< class F > function& operator=( F&& f );
overload of operator=
, which has the requirement:
This operator does not participate in overload resolution unless
f
is Callable for argument typesArgs...
and return typeR
.
Which is
INVOKE<R>(f, std::declval<ArgTypes>()...)
is well-formed in unevaluated context.
And std::function<R(Args...>::operator()(Args... args)
is similarly defined as doing INVOKE<R>(f, std::forward<Args>(args)...)
, returning nothing in the case R
is void
.
The exposition-only operation
INVOKE<R>(f, arg_0, arg_1, arg_2, ..., arg_N)
is defined as follows:
If
R
is (possibly cv-qualified)void
static_cast<void>(INVOKE(f, arg_0, arg_1, arg_2, ..., arg_N)).
I.e. it explicitly discards the result by casting to void