
On Sun, Apr 11, 2010 at 5:47 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/11/2010 12:29 PM, Eric Niebler wrote:
On 4/11/2010 9:37 AM, Daniel Walker wrote:
On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric@boostpro.com> wrote:
If Boost.TR1 advertises itself as an implementation of TR1, then it should have an implementation of result_of that doesn't rely on decltype. (Waiting for John to jump in here.) That way, libraries like Proto that need the tr1 behavior (until decltype is fixed) can use std::tr1::result_of from boost/tr1/functional.hpp and forget about it. This should be possible in the 1.44 time frame and is a good long-term solution.
Agreed.
Note that to make this happen, you'll need to coordinate with John. The way Boost.TR1 works is like this:
- If the platform implements <tr1/foo_header>, include it. Otherwise, - Include <boost/foo_header.hpp> and bring boost::foo into the std::tr1 namespace with a using declaration.
If boost::result_of sometimes uses decltype, the above won't work because then std::tr1::result_of will sometimes use decltype. It seems to me that <boost/utility/result_of.hpp> should expose a boost::tr1_result_of that can be used by <boost/tr1/result_of.hpp> to get the TR1 behavior regardless of whether decltype exists or not.
I opened a ticket for this (milestone 1.44) and attached a patch: https://svn.boost.org/trac/boost/ticket/4084. I noticed that the decltype change to result_of was causing regression failures in TR1 by making the implementation of TR1's result_of non-compliant. The patch fixes the issue and adds a boost::tr1_result_of.
I like the idea and the patch looks good. How do I go about getting it on trunk? I don't believe I have check-in rights.
The regression test failures may be more evidence that the change to result_of was a bad idea (as well-intentioned as it may have seemed). This patch may not be the last word on the issue. I'm still uncomfortable with the change to boost::result_of, which is likely to break users' code. Perhaps we could place the new decltype implementation on a compile-time switch (BOOST_RESULT_OF_USE_DECLTYPE?) so that users can opt in. That wouldn't eliminate the need for boost::tr1_result_of or something like it, though.
Ultimately, boost::result_of should behave as intended whenever possible; i.e. it should evaluate to the type of a call expression. The fact that in c++03 it was possible for result_of to evaluate to a type other than the type of a call expression is a bug. In c++0x, the compiler can detect these situations and report them as errors. That's a good thing. Now, I understand that it's too much to ask before the 1.43 release that boost compile without error or regression in c++0x mode on gcc or msvc, so I agree with sweeping this problem under the rug for this release. But in the future, it is reasonable to expect regressions when porting boost to c++0x. One type of regression will be situations when result_of was evaluated to a type other than the type of the call expression. Usually, this will be due to an unintended programming error, so correcting the problem will be an improvement. Sometimes, it will be due to a quirk of the TR1 protocol; for example, allowing result_of in context where the call expression type is incomplete, as was the case with Proto. Perhaps, result_of is not the best solution in Proto's situation, and Proto should specify return types in its function signatures in some other way... Regardless, given available technology, result_of should evaluate to the type of the call expression; in c++0x the technology is available and result_of should use it. Daniel Walker