|
Boost : |
From: Doug Gregor (dgregor_at_[hidden])
Date: 2007-01-08 10:36:57
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk