We've discussed making boost::ref/boost::cref work for arbitrary functions 
objects before. I just committed a version of ref.hpp that supports this 
ability to the sandbox. With this code, you can write:

  std::transform(c.begin(), c.end(), out, boost::ref(f));

or, if you don't want the return type deduced, specify it as in Boost.Bind:

  std::transform(c.begin(), c.end(), out, boost::ref<float>(f));

Features of this implementation:
  - Return type deduction (discussed below)
  - Argument type deduction  (discussed below)
  - Able to handle function objects that have multiple arities (e.g., can be 
invoked with 0 or 2 arguments)

The implementation is here:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost-sandbox/boost-sandbox/boost/ref.hpp?rev=HEAD&content-type=text/plain

Testcases are here:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost-sandbox/boost-sandbox/libs/utility/ref_call_test.cpp?rev=HEAD&content-type=text/plain

------Return type deduction------
  - If the user specifies a return type, use it
  - Otherwise, if the class has a result_type typedef, use it
  - Otherwise, use Boost.Lambda-style sig<arg_types>::type

------Argument type deduction------  
  - If typedefs arg1_type, arg2_type, ..., argN_type are available, use 
_precisely_ those argument types (as in Boost.Function) to define 
operator()(arg1_type), operator()(arg1_type, arg2_type), etc, up to 'N' for 
that particular class.

  - Otherwise, if the class has an argument_type typedef, define 
operator()(const argument_type&). If the class also has first_argument_type 
and second_argument_type, define 
  operator()(const first_argument_type&, const second_argument_type&);

  - Otherwise, if the class has first_argument_type and second_argument_type, 
define 
  operator()(const first_argument_type&, const second_argument_type&);

  - Otherwise, define a bunch of function templates that deduce the argument 
types at call time, e.g.,
    template<typename T1, typename T2, ..., typename TN>
    return-type-as-mentioned-before operator()(T1&, T2&, ..., TN&);

There is always an operator() that takes no arguments.

------Compatibility------
This version of ref.hpp is backwards-compatible with the existing version of 
ref.hpp on a compiler that can handle the new ref.hpp (needs partial 
specialization and proper SFINAE handling). At some point I'll write a 
stripped-down version that other compilers can handle. The stripped-down 
version will feel a lot more like boost::bind:
  - Return type deduction will be limited to using a user-supplied return 
type, or else using ::result_type
  - Argument type deduction won't look for argN_types, argument_type, or 
first/second_argument_type, but will fall back to the set of function 
templates that deduce the argument types from the call.

        Doug
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to