All quotes are from N3797.
4/3 [conv]
An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t
This implies no expression can be implicitly converted to void
, as void t=e
is illegal for all expressions e
. This is even true if e
is an expression of type void
, such as void(3)
.
So an expression of type void
cannot be implicitly converted to void
.
Which leads us to:
20.9.2/2 Requirements [func.require]
Define INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) implicitly converted to R .
In short, INVOKE(f, t1, t2, ..., tN, R)
is never valid when R
is void
, as nothing (including void
) can be implicitly converted to void
.
As a result of this, all std::function<void(Args...)>
have the property !*this
and thus cannot be called, as the only constructors that do not have !*this
as a postcondition (or do not copy such state from another function
of the same type) require Callable
of one of the parameters.
20.9.11.2/7 Class template function [func.wrap.func]
Requires: F shall be CopyConstructible . f shall be Callable ( 20.9.11.2 ) for argument types ArgTypes and return type R . The copy constructor and destructor of A shall not throw exceptions.
20.9.11.2/2 Class template function [func.wrap.func]
A callable object f of type F is Callable for argument types ArgTypes and return type R if the expres- sion INVOKE (f, declval()..., R) , considered as an unevaluated operand (Clause 5 ), is well formed ( 20.9.2 ).
As demonstrated above, there are no Callable
expressions for std::function<void(Args...)>
.
If somehow such a std::function<void(Args...)>
where found, invoking operator()
would be ill formed:
invocation [func.wrap.func.inv]
Effects: INVOKE (f, std::forward(args)..., R) ( 20.9.2 ), where f is the target ob- ject ( 20.9.1 ) of *this .
as INVOKE(f, std::forward<ArgTypes>(args)..., void)
is ill formed for all arguments and f
.
Is this line of reasoning sound?