... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

Robert M. Münch robert.muench at saphirion.com
Thu Oct 24 17:57:46 UTC 2019


On 2019-10-23 17:22:38 +0000, Ali ‡ehreli said:

> On 10/23/2019 02:43 AM, Robert M. Münch wrote:
> 
>  >> Unfortunately, member function template instances are never virtual
>  >> functions, so you can't override them.
>  >
>  > What I don't understand is:
>  >
>  > 1. The RX lib has a member function template and than an instance of it
>  > using type Oberver!E.
>  >
>  > 2. I'm creating a new type and want to use the same pattern but now with
>  > my type. But it seems that D reduces my own type which leads to the
>  > ambigty of which function now to use. Whereas I would expect that D uses
>  > the most specific type first.
> 
> That is exactly the case (for D, C++, etc.). However, the function must 
> be virtual. Imagine an object is being accessed by it base interface, 
> only the virtual function calls will be dispatched to the most specific 
> type. Non-virtual functions will be called on the base type.

Yes, I know and the problem seems to be what you mentioned before: "But 
I think you have a member function template in the base class. 
Unfortunately, member function template instances are never virtual 
functions, so you can't override them."

Is there a reason why these type of functions are not virtual or can't 
be made virtual?

> For that reason, even though I've managed to remove your compilation 
> error below, you will not like how it behaves.
> 
>  > The pastbin is the minimal code example. And yes, I'm sure there is a
>  > (simple) way out...
> 
> Replacing FilterSubject with the following removes the compilation error:
> 
> static class FilterSubject : SubjectObject!message {
> 
>    SI spitialIndex;
> 
>    this(){
>      spitialIndex = new SI();
>    }
> 
>    auto subscribe(T)(T t)
>    if (!is (T == myWidget))
>    {
>      return typeof(super).subscribe(t);
>    }
> 
>    Disposable subscribe(T)(T observer)
>    if (is (T == myWidget))
>    {
>      spitialIndex.insert(observer.x, observer.y, 
> cast(long)cast(void*)observer);
> 
>      return NopDisposable.instance;
>    }
> }

Ah, that's pretty neat. I think that is what I need. I have to get used 
to this template variant handling feature.

> However...
> 
>    auto rx_message = new FilterSubject;
> 
> The type of rx_message is FilterSubject above. When one calls 
> .subscribe() on it, only FilterSubject.subscribe templates will be 
> involved. Perhaps that's exactly what you want.

Yes.

> However... :)
> 
> Accessing rx_message through a base class interface will call a 
> different set of .subscribe() functions (the ones on the base even for 
> myWidget!):
> 
>    SubjectObject!message rx_message = new FilterSubject;
> 
> Now rx_message is the base type and only now you get "Hit!" printed.

Yes, that fits. Because only when thîs specific type is used the 
specialized implementation should be used.

> Again, maybe this is exactly what you want but beware that different 
> sets of functions will be called depending on what interface of the 
> object you are using.

Yes, I understand and this is a very elegant way to keep the same 
interface but with different behaviour depending on the type. Very 
useful.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



More information about the Digitalmars-d-learn mailing list