Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-01-08 13:19:34

Doug Gregor wrote:
> 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

It doesn't really take that esoteric of a case to be useful, though.
Let's consider a variadic function wrapper and a call that doesn't fit
the arity of the wrapped object:

Now, with "SFIANE propagation" we get "no match for call to
<wrapper>..." reported in client code - without "SFINAE propagation" we
get "no match for call to <wrapped>...", reported in the gory details of
the wrapper and (possibly lots of) trace diagnostics burying it.

> Now, in C++0x, the metaprogramming-based implementation and
> specification of result_of is going to disappear in favor of
> decltype.

We can remove that nested result class template, then...

> 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."

... but I guess we might be able to use that very language extension to
detect whether a function object has a call operator that suits given
argument types.

Further, a client may still define a specialization for std::result_of
to control whatever is in there.

Not trying to convince you - just thinking aloud...

Thanks for your reply.


Boost list run by bdawes at, gregod at, cpdaniel at, john at