Boost logo

Boost :

Subject: Re: [boost] RFC: type erasure
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2011-05-24 19:39:54


On Mon, May 23, 2011 at 11:01 PM, Steven Watanabe <watanabesj_at_[hidden]> wrote:
>
> Okay.  Problem 1: Name hiding for member functions.
>
> typedef mpl::vector<
>    callable<int(int)>,
>    callable<double(double)>
>> test_concept;
>
> If we just use the basic definition of
> concept_interface, the second overload
> will hide the first since the inheritance
> structure looks like:
>
> struct callable1 {
>    int operator()(int);
> };
>
> struct callable2 : callable1 {
>    double operator()(double);
> };
>

This can be solved by an "using callable1::operator();" . I just had
to solve a very similar problem 20 minutes ago, but in my case all the
elements in the inheritance chains only had operator() in need of
un-hiding.

I guess the problem in your case is that in general your callable2 is
not necessarily inheriting from something that is callable, that is,
you are using operator() as the name but it could be anything. A
solution is adding every possible name (but with special arguments so
that they won't actually partecipate in overload resolution) in the
most base class and adding an "using <every possible name> at every
level of the inheritance:

struct base {
   struct dont_call_me{}
    void operator()(dont_call_me);
    void operator+(dont_call_me);
    void construct(dont_call_me);
}

struct negable : base {
     using base::operator();
     using base::operator+;
     using base::construct;

    void operator-(); // can't be overloaded so no risk of hiding
}

struct addable : negable {
     using negable::operator();
     using negable::operator+;
     using negable::construct;

     whatever operator+(whatever);
};

struct callable2 : addable {
     using addable::operator();
     using addable::operator+;
     using addable::construct;
     whatever operator()(whatever);
};

struct callable1 : callable2 {
     using callable2::operator();
     using callable2::operator+;
     using callable2::construct;
     whateverelse operator()(whateverelse);

}

struct constructible : callable2 {
     using callable2::operator();
     using callable2::operator+;
     using callable2::construct;

     void construct(args..)

     template<class ...T>
     constructible(T... args) { construct(args...); } // calls this
construct or any in the base classes
}

Probably it will break in some cases I'm not foreseeing. Will
definitely not work for user specified foo-able.

HTH,

-- 
gpd

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