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

Reply via email to