Is the code below valid C++ according to the C++11 or C++14 standard?
#include <functional>
int ReturnInt()
{
return 5;
}
int main( int argc, char **argv )
{
std::function< void () > BoundType = ReturnInt;
return 0;
}
The code compiles fine with the latest cygwin versions of gcc (4.8.3) and clang (4.3.2) but not with Visual Studio 2013, Visual Studio November 2013 CTP or the Visual Studio 14 preview. It also compiles on all platforms if std::function is changed to boost::function.
I found this other stack overflow question that suggests it should work.
The code is undefined behavior in C++11, and ill-formed in C++14. C++14 adds this Remark to the specification of this constructor:
Remarks: These constructors shall not participate in overload resolution unless
f
is Callable (20.9.11.2) for argument typesArgTypes...
and return typeR
.
Callable is defined in [func.wrap.func]/p2:
A callable object
f
of typeF
is Callable for argument typesArgTypes
and return typeR
if the expression INVOKE(f, declval<ArgTypes>()..., R)
, considered as an unevaluated operand (Clause 5), is well formed (20.9.2).
For this INVOKE to be well formed, the return type of INVOKE without the R
must be implicitly convertible to R
([func.require]/p2).
In C++11 these statements were under a Requries clause, which means it is up to the client to get them right, and if the client fails, anything can happen, including successful compilation.
This was changed by LWG 2132.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With