On Jun 20, 2013, at 1:59 AM, Nathan Crookston
Hi Daniel & all,
I'm updating the patch for ticket 7753 ( https://svn.boost.org/trac/boost/ticket/7753). I've made the requested changes to the patch, but I had a question on how to best explain which macro to define if, for example, you want result_of to work with C++11 lambdas. In the past, users with a pre-N3276 decltype have been advised to just #define BOOST_RESULT_OF_USE_DECLTYPE, with the explanation that "it's probably just going to work." While that advice is true, there are cases where this doesn't work; hence the addition of BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK.
To explain why you'd define the FALLBACK macro over the USE_DECLTYPE macro, I'm thinking of including a paragraph like the following.
"The question naturally arises on why have both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK. In many situations, BOOST_RESULT_OF_USE_DECLTYPE will work well, even with pre-N3276 decltype. However, there are cases where a post-N3276 decltype is required to correctly deduce the return type of a functor. If a translation unit includes a functor whose return type is only deducible with TR1 or a post-N3276 decltype, using result_of with, e.g. a C++11 lambda function, will fail without BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK. If the macro BOOST_NO_CXX11_DECLTYPE_N3276 is defined and BOOST_NO_CXX11_DECLTYPE is not defined when including result_of.hpp, defining BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK is the safest option that will allow you to deduce C++11 lambda return types."
My question is, am I over explaining it? Of course, I'd rather have BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK defined automatically for compilers like VC10, g++4.5, etc., and include text like the following:
"If you rely on the result of calling a nullary functor to be void, regardless of the actual return type, or if your code is not written to handle cases other than BOOST_RESULT_OF_USE_TR1 and BOOST_RESULT_OF_USE_DECLTYPE, you may wish to explicitly define one of those symbols prior to including result_of."
Either way, comments welcome.
OK, Nathan, I cleaned up your patch and committed the changes. (One more modification: I moved boost::cpp0x_result_of to boost::detail::cpp0x_result_of, since this is an implementation detail; people who are only interested in C++0x result_of should simply use std::result_of.) I added the following documentation. "Additionally, boost::result_of provides a third mode of operation, which some users may find convenient. When BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK is defined, boost::result_of behaves as follows. If the function object has a member type result_type or member template result<>, then boost::result_of will use the TR1 protocol. Otherwise, boost::result_of will use decltype. Using TR1 with a declytpe fallback may workaround certain problems at the cost of portability. For example: Deficient compiler: If your code requires boost::result_of to work with incomplete return types but your compiler's decltype implementation does not support incomplete return types, then you can use the TR1 protocol as a workaround. Support for incomplete return types was added late in the C++11 standardization process (see N3276) and is not implemented by some compilers. Deficient legacy code: If your existing TR1 function object advertises a different type than the actual result type deduced by decltype, then using TR1 with a decltype fallback will allow you to work with both your existing TR1 function objects and new C++11 function object. This situation could occur if your legacy function objects misused the TR1 protocol. See the documentation on known differences between boost::result_of and TR1." - Daniel