|
Boost : |
Subject: Re: [boost] (Boost.)Overload vs Boost.Functional/OverloadedFunction (was Re: Status of proposed boost.overload?)
From: Marco Cecchetti (mrcekets_at_[hidden])
Date: 2012-03-28 09:56:59
On Wed, 28 Mar 2012 00:35:57 +0200, Steven Watanabe <watanabesj_at_[hidden]>
wrote:
> AMDG
>
> On 03/27/2012 02:10 PM, lcaminiti wrote:
>>
>> BTW, I wasn't able to handle polimorphic functions. For example, the
>> following will not work :(
>>
>> struct poly {
>> template<typename T>
>> void operator()( T const& x ) { std::cout << "poly" << std::endl; }
>> };
>>
>> void mono( int x, int y ) { std::cout << "mon" << std::endl;
>>
>> overload_function< void(int, int), /* some type which I couldn't figure
>> out
>> */ > f(mono, poly);
>> f(1, 2); // call mono
>> f(123); // call poly
>> f("abc"); // call poly
>>
>> // or even harder
>> auto g = make_overloaded_function(mono, poly);
>> g(1, 2); // call mono
>> g(123); // call poly
>> g("abc"); // call poly
>>
>> Can your library handle polymorphic functions?
>>
>
> No. This is fundamentally impossible.
> Let's ignore the overload part for now.
>
> We're trying to define a class F, such that:
>
> For any types T and U, such that T is
> copy constructible and T is callable
> with an argument of type U:
>
> Given an object t of type T, and
> an object u of type U.
>
> F f(t);
>
> shall be valid and f shall store a copy of t.
> Call this copy t_f. Now, f(u) shall compile
> and shall call t_f(u).
>
> Let's assume that F exists.
> Now, suppose that T is declared only in
> translation unit A, and U is declared
> only in translation unit B. Further, suppose
> that T is a class type with a templated function
> call operator. The constructor F(t) can be
> executed in A, and the function call can be
> executed in B. The result must call T::operator()<U>.
> However, T and U are never available in the
> same translation unit, so T::operator()<U> cannot
> be instantiated. -><-
Clean exposition :)
> Therefore, we can conclude that type erasure
> cannot handle polymorphic functions like this,
> without adding further restrictions.
>
> Some possibilities are:
> a) type erase the argument to T::operator().
> b) Limit T and/or U to some fixed set of types.
> (a la Boost.Variant)
> c) Allow T/U pairs to be registered dynamically
> and fail at runtime if there is no viable
> function.
(b) is exactly what (Boost.)Overload does.
It supports only a finite overload set and provides a method
for setting up a copy of a polymorphic function object for
each object target related to a call signature supported
by both the given instantiation of the template class
overload and the passed function object itself.
Passing to another issue, do you know a way for getting
the call signature of the call object type resulting from a
lambda or phoenix bind expression at least in the case that
the call object is monomorphic ?
-- Marco
-- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk