Boost logo

Boost :

Subject: Re: [boost] (Boost.)Overload vs Boost.Functional/OverloadedFunction (was Re: Status of proposed boost.overload?)
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2012-03-27 18:35:57


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. -><-

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.

(As the author of a library for general type
erasure, I've spent an inordinate amount of
time thinking about this problem.)

In Christ,
Steven Watanabe


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk