|
Boost : |
Subject: Re: [boost] [functional] adding overload
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-01-16 17:08:38
On Mon, Jan 16, 2012 at 9:11 AM, Roman Perepelitsa
<roman.perepelitsa_at_[hidden]> wrote:
> 2012/1/16 Lorenzo Caminiti <lorcaminiti_at_[hidden]>
>
>> On Sun, Jan 15, 2012 at 9:06 PM, Nathan Ridge <zeratul976_at_[hidden]>
>> wrote:
>>
>> > I like boost::functional::overload. You can then add a convenience
>> > function make_overload() with creates one without having to specify
>>
>> Yes, I will add boost::functional::make_overload as well.
>>
>
> I don't think it can be implemented in general case. What signature will it
> have?
It was suggested during Boost.Local review to use make_overload with
auto (or BOOST_AUTO):
auto f = make_overload(f1, f2, f3);
For example:
void print_s(const std::string& s) { std::cout << s << std::endl; }
void print_i(int i) { std::cout << i << std::endl; }
void print_d(double d) { std::cout << d << std::endl; }
int main(void) {
boost::function<void (double)> pd = print_d;
print_s("abc");
print_i(123);
pd(1.23);
std::cout << std::endl;
boost::functional::overload<
void (const std::string&)
, void (int)
, void (double)
> print(print_s, print_i, pd);
print("abc");
print(123);
print(1.23);
std::cout << std::endl;
BOOST_AUTO(p, boost::functional::make_overload(&print_s, &print_i, pd));
p("abc");
p(123);
p(1.23);
std::cout << std::endl;
return 0;
}
This can be implemented using a suitable function_type that returns
the function type result_type (arg1_type, ...) from a function type,
function pointer, function reference, or from a functor which defines
the types result_type, arg1_type, ... (as for example boost::function
does). I don't think such implementation of function_types exists...
IMO, I'd be nice to make boost::function_types::function_type (that
right now only accepts a mpl sequence) to also accept function types,
function pointer, function references, and functor types defining
result_type, arg1_type, etc.
I'd implement function_type for functors like this:
#include <boost/functional/overload.hpp>
#include <boost/function.hpp>
#include <boost/function_types/is_function.hpp>
#include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/is_function_reference.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/placeholders.hpp>
#include <iostream>
#include <string>
#include <typeinfo>
namespace boost { namespace functional {
namespace detail {
template<typename F, int Arity = -1>
struct functor_type {
typedef typename functor_type<F, F::arity>::type type;
};
template<typename F>
struct functor_type<F, 0> {
typedef typename F::result_type (type)(
);
};
template<typename F>
struct functor_type<F, 1> {
typedef typename F::result_type (type)(
typename F::arg1_type
);
};
template<typename F>
struct functor_type<F, 2> {
typedef typename F::result_type (type)(
typename F::arg1_type
, typename F::arg2_type
);
};
} // namespace detail
template<typename F>
struct function_type {
typedef
typename boost::mpl::if_<boost::function_types::is_function<F>,
boost::mpl::identity<F>
,
typename boost::mpl::if_<boost::function_types::
is_function_pointer<F>,
boost::remove_pointer<F>
,
typename boost::mpl::if_<boost::function_types::
is_function_reference<F>,
boost::remove_reference<F>
,
detail::functor_type<F>
>::type
>::type
>::type
::type type;
};
template<typename F0, typename F1, typename F2>
boost::functional::overload<
typename function_type<F0>::type
, typename function_type<F1>::type
, typename function_type<F2>::type
>
make_overload(F0 f0, F1 f1, F2 f2) {
return boost::functional::overload<
typename function_type<F0>::type
, typename function_type<F1>::type
, typename function_type<F2>::type
>(f0, f1, f2);
}
} } // namespace
--Lorenzo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk