
[Part 2 of 3] Daniel Walker wrote:
2) Nullary function objects [...] struct functor { template<class> struct result { typedef int type; }; int operator()(); };
There are two types of misusage of result_of: A. Wrong definition of return types B. Return type evaluation with uncallable signatures I think the above code (i.e. the code with nullary function objects that do not specialize boost::result_of/tr1_result_of class template) belongs to A. The consequence of "TR1-style result_of has the default type `void` for nullary calls" is related to B. B is allowed with TR1-style result_of in many cases, since * Callability is not checked for function pointers. * Callability is not checked for function objects having `result_type`. * Nested class template `result` is often partially specialized (in a way that uncallable signatures are allowed). * Nullary calls are always allowed. With decltype-based result_of, B is not allowed at all. TR1-style result_of has the default type `void` to allow template <typename F> struct FuncWrapper { typename boost::result_of<F()>::type operator()(); /* ... */ }; for function objects that are not nullary-callable. But, with decltype-based result_of, this code fails to compile for non-nullary function objects. I think this is an important breaking change. We can avoid compiler errors using variadic templates. But, IIRC, VC++ 11 does not implement variadic templates. Regards, Michel