On Wed, Nov 28, 2012 at 9:21 PM, Nathan Crookston <nathan.crookston@gmail.com> wrote:

Jeffrey Lee Hellrung, Jr. wrote:
Nathan Crookston wrote:
[...]

With or without a change to result_of, I believe there's value in allowing the user to explicitly specify the result_type of a callable object passed to transformed.  Ticket #7748[1] contains a patch which permits that.

I would think a preferable (in the sense of separation of concerns, modularity, what-have-you) solution would be an addition to Boost.Functional (or whatever) that basically wraps a callable object and forces its result_type to be some specified template parameter. E.g.,

template< class F, class R >
struct result_binder
{
  F f;
  typedef R result_type;
  template< class... T >
  result_type operator()(T&&... x) const
  { return f(std::forward<T>(x)...); }
};

template< class R, class F >
result_binder<F,R>
bind_result(F&& f)
{ return result_binder<F,R>{std::forward<F>(f)}; }

I agree that such an object generator (along with Michel's make_tr1_functor) would be useful.   There are two reasons why I feel extending transformed would be useful whether or not the previous object generators were added:

1. Both this and Michel's suggestions require C++11 features -- either decltype or rvalue references.  Extended transformed allows the creation of a result_binder struct to be delayed until the reference type of the input range is available.  This would make it usable for non-lambda instances where an explicit return type is desired without the fuss of defining a separate functor (assuming the functor to be wrapped cannot be changed).  I believe a correct C++03 version of result_binder would need a large number of operator() overloads depending on how many arguments it intends to forward.

True, though this sounds like more of an implementation concern (don't get me wrong, it's a valid concern) than a capability concern.

2. Such a syntax (transformed<R>(...)) has been used previously -- boost bind's docs, referring to bind<R> syntax, state:  "It is generally used with function objects that do not, or cannot, expose result_type."[1]  Without begging for an Emerson quote, I believe consistency with bind in this case will improve the usability enough to justify the required changes.  Note also that this is the only current adaptor[2] which takes a function object with arbitrary return type (others must return something which is convertible to bool).  Note also that the changes are a pure extension (previous usage continues unchanged).

I'm personally not swayed but it's a fair rationale nonetheless and ultimately your call since I'm not doing it :)

Thanks,
Nate

[1] http://www.boost.org/doc/libs/1_52_0/libs/bind/bind.html#Q_forms
[2] I previously proposed a zip/unpack adaptor -- if that were adopted, unpack would be a second range object which would benefit from an explicit return type.

- Jeff