The boost::function FAQ item 3 specifically addresses the scenario I am interested in:
Why are there workarounds for void
returns? C++ allows them! Void returns
are permitted by the C++ standard, as
in this code snippet:void f(); void g() { return f(); }This is a valid usage of
boost::function because void returns
are not used. With void returns, we
would attempting to compile ill-formed
code similar to:int f(); void g() { return f(); }In essence, not using void returns
allows boost::function to swallow a
return value. This is consistent with
allowing the user to assign and invoke
functions and function objects with
parameters that don’t exactly match.
Unfortunately, this doesn’t work in VS2008:
int Foo();
std::tr1::function<void()> Bar = Foo;
This produces errors starting with:
c:\Program Files\Microsoft Visual Studio 9.0\VC\include\xxcallfun(7) : error C2562: 'std::tr1::_Callable_fun<_Ty>::_ApplyX' : 'void' function returning a value
Is this a failing of the VS2008 TR1 implementation? Does this work in VS2010? Does TR1 address this capability? How about C++0x?
I believe tr1 addresses this issue. N1836 (the latest tr1 draft) says:
In your example R is void, and so the last part of the requirements for
Callable(convertible to R) is ignored.However it looks like C++0x (C++11) changes the rules. In C++11
Callableis defined asINVOKE(f, t1, t2, ..., tN, R)which is defined in [func.require] as requiringINVOKE(f, t1, t2, ..., tN)to be implicitly convertible to R, with no exception for when R is void. So in C++11, your example should fail.