
Hi Tobias, On Dec 27, 2006, at 7:51 AM, Tobias Schwinger wrote:
Hi Doug and Boost community,
I noticed that the Boost implementation of result_of uses inheritance to forward the type member of a nested result metafunction, so that result_of<...>::type can result in a substitution failure (and not an error when used in an appropriate context) if the nested result class template does not have a type member.
It's surely a nice feature (also because it usually stops trace diagnostics at a reasonable point in case of an error). Should the standard text perhaps encforce that kind of implementation - e.g:
[tr.func.ret.ret] 2 5 (b)
If N>0, result_of<F(T1, T2, ... TN)> inherits from F::result<F(T1, T2, ... TN)>
? Comments?
Hmmm, that was an accidental feature... so we could construct a case where one could exploit this functionality: struct X { template<typename F> struct result {}; template<> struct result<X(int&)> { typedef int& type; } int& operator()(int&); operator bool() const; }; template<typename F> typename boost::result_of<F(int&)>::type foo(F f); bool foo(bool); X x; foo(x); // works if we use inheritance for X::result<X(int&)>, fails otherwise Now, in C++0x, the metaprogramming-based implementation and specification of result_of is going to disappear in favor of decltype. With a decltype-based implementation, the code above would be ill-formed, so I think the right answer is "do the same thing that the decltype implementation would do." From this viewpoint, the SFINAE-propagating feature of Boost's result_of is really a bug that we should fix. Cheers, Doug