|
Boost : |
Subject: Re: [boost] [local] Help for the Alternatives section
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-05-08 13:06:09
On Sun, May 8, 2011 at 11:22 AM, Mathias Gaunard
<mathias.gaunard_at_[hidden]> wrote:
> On 08/05/2011 16:04, Lorenzo Caminiti wrote:
>
>>> auto /* or the real type */ l = overload(l1, l2);
>>
>> Does Boost already have a functor overloader like overload() above?
>
> I do not think so.
>
>
>
>> template<typename F0, typename F1, typename F2 = void, typename F3 = void>
>> struct overload {
>> };
>>
>> template<typename F0R, typename F0A0, typename F1R, typename F1A0>
>> struct overload<F0R (F0A0), F1R (F1A0)> {
>> overload(boost::function<F0R (F0A0)> f0, boost::function<F1R (F1A0)>
>> f1):
>> f0_(f0), f1_(f1) {}
>> F0R operator()(F0A0 a0) const { return f0_(a0); }
>> F1R operator()(F1A0 a0) const { return f1_(a0); }
>> private:
>> boost::function<F0R (F0A0)> f0_;
>> boost::function<F1R (F1A0)> f1_;
>> };
>>
>> // More specializations to overload also with F2, F3, etc.
>
> The type erasure appear unnecessary, and this implementation has big
> forwarding problems.
>
>
> What about
>
> template<typename F0, typename F1>
> struct overload_t : F0, F1
> {
> overload_t(F0 const& f0, F1 const& f1) : F0(f0), F1(f1)
> {
> }
>
> using F0::operator();
> using F1::operator();
> };
>
> template<typename F0, typename F1>
> overload_t<F0, F1> overload(F0 const& f0, F1 const& f1)
> {
> return overload_t<F0, F1>(f0, f1);
> }
Yes, makes sense. Using your suggestion:
#include <boost/local/function.hpp>
#include <boost/function.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
#include <string>
namespace boost { namespace local { namespace function {
template<typename F0, typename F1, typename F2 = void, typename F3 = void>
struct overloaded {};
// Specialization for 2 functions.
template<typename F0, typename F1>
struct overloaded<F0, F1>: F0, F1 {
overloaded(F0 const& f0, F1 const& f1):
F0(f0), F1(f1) {}
using F0::operator(); using F1::operator();
};
template<typename F0, typename F1>
overloaded< boost::function<F0>, boost::function<F1> >
overload(
boost::local::aux::function<F0> const& f0
, boost::local::aux::function<F1> const& f1
) {
return overloaded< boost::function<F0>, boost::function<F1> >(f0, f1);
}
// Specialization for 3 functions.
template<typename F0, typename F1, typename F2>
struct overloaded<F0, F1, F2>: F0, F1, F2 {
overloaded(F0 const& f0, F1 const& f1, F2 const& f2):
F0(f0), F1(f1), F2(f2) {}
using F0::operator(); using F1::operator(); using F2::operator();
};
template<typename F0, typename F1, typename F2>
overloaded< boost::function<F0>, boost::function<F1>, boost::function<F2> >
overload(
boost::local::aux::function<F0> const& f0
, boost::local::aux::function<F1> const& f1
, boost::local::aux::function<F2> const& f2
) {
return overloaded< boost::function<F0>, boost::function<F1>,
boost::function<F2> >(f0, f1, f2);
}
// More specializations for more functions...
}}} // namespace boost::local::function
// More specializations to overload also with F2, F3, etc.
int main() {
char sep = '\n';
void BOOST_LOCAL_FUNCTION_PARAMS(const double& item, const bind& sep) {
std::cout << item << sep;
} BOOST_LOCAL_FUNCTION_NAME(print_double)
void BOOST_LOCAL_FUNCTION_PARAMS(const std::string& item, const bind& sep) {
std::cout << item << sep;
} BOOST_LOCAL_FUNCTION_NAME(print_string)
void BOOST_LOCAL_FUNCTION_PARAMS(const char& item, const bind& sep) {
std::cout << item << sep;
} BOOST_LOCAL_FUNCTION_NAME(print_char)
boost::local::function::overloaded<
boost::function< void (const double&) >
, boost::function< void (const std::string&) >
, boost::function< void (const char&) >
> print = boost::local::function::overload(
print_double, print_string, print_char);
std::vector<double> d(2);
d[0] = 1.2; d[1] = 3.4;
std::for_each(d.begin(), d.end(), print);
std::vector<std::string> s(3);
s[0] = "ab"; s[1] = "cd"; s[2] = "ef";
std::for_each(s.begin(), s.end(), print);
char c[4] = {'x', 'y', 'z', 'w'};
std::for_each(c, c + 4, print);
return 0;
}
> Function pointers will have to be dealt with specially, though.
This is not an issue for Boost.Local. If overload() and overloaded<>
where to be added to Boost.Function instead, this case should be
handled. I will make a note of this in Boost.Local docs rationale.
Thanks a lot.
On a separate note, Boost.Local does not allow to name a local
function after an operator. Would that ever be useful?
-- Lorenzo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk