www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static virtual members

reply BCS <BCS_member pathlink.com> writes:
Is there any way to make static virtual members?

Here is a sketch of what I want to do:

int fn1(int j){return j;}
int fn2(int j){return j*2;}

class A
{
	static virtual int function(int) v = &fn1;

	int i;

	int get(){return v(i);}	// uses the v of the object calling get.
}

class B : A
{
	static virtual int function(int) v = &fn2;
}

the problem comes from the fact that fn1 and fn2 must be part of another 
module, therefor they can't be regular members of A & B. This should be 
implementable by adding another pointer to the vtbl, I could even live 
with a restriction to const pointers.

Is this already doable? Does anyone have any suggested workarounds (this 
is used in time critical code)? Does anyone see any problems with this idea?
Dec 20 2005
next sibling parent Chris Sauls <ibisbasenji gmail.com> writes:
BCS wrote:
 Is there any way to make static virtual members?
 
 Here is a sketch of what I want to do:
 
 int fn1(int j){return j;}
 int fn2(int j){return j*2;}
 
 class A
 {
     static virtual int function(int) v = &fn1;
 
     int i;
 
     int get(){return v(i);}    // uses the v of the object calling get.
 }
 
 class B : A
 {
     static virtual int function(int) v = &fn2;
 }
 
 the problem comes from the fact that fn1 and fn2 must be part of another 
 module, therefor they can't be regular members of A & B. This should be 
 implementable by adding another pointer to the vtbl, I could even live 
 with a restriction to const pointers.
 
 Is this already doable? Does anyone have any suggested workarounds (this 
 is used in time critical code)? Does anyone see any problems with this 
 idea?

I just tested this, and I thought it would already work with a 'this.v(i)' call, but I was wrong. Maybe this should be a new behavior of the existing 'override' attribute? # class A { # static auto v = &fn1; # # int i; # # int get () { return this.v(i); } # } # # class B { # override static auto v = &fn2; # } -- Chris Sauls
Dec 20 2005
prev sibling parent reply Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= <dawid.ciezarkiewicz gmail.com> writes:
BCS wrote:

 Is there any way to make static virtual members?
 
 Here is a sketch of what I want to do:
 
 int fn1(int j){return j;}
 int fn2(int j){return j*2;}
 
 class A
 {
 static virtual int function(int) v = &fn1;
 
 int i;
 
 int get(){return v(i);}       // uses the v of the object calling get.
 }
 
 class B : A
 {
 static virtual int function(int) v = &fn2;
 }
 
 the problem comes from the fact that fn1 and fn2 must be part of another
 module, therefor they can't be regular members of A & B. This should be
 implementable by adding another pointer to the vtbl, I could even live
 with a restriction to const pointers.
 
 Is this already doable? Does anyone have any suggested workarounds (this
 is used in time critical code)? Does anyone see any problems with this
 idea?

I'm not sure what you're tring to achive but the voices are telling me you're overcomplicated. You want something like this, maybe: int fn1(); int fn2(); class A { private: int function() v; public: this() { v = &fn1; } int get() { return v(); } } class B : A { public: this() { v = &fn2; } } If not please explain more and I've try to help you if I can.
Dec 21 2005
parent reply BCS <BCS_member pathlink.com> writes:
Dawid Ciężarkiewicz wrote:
 BCS wrote:
 
 
Is there any way to make static virtual members?

Here is a sketch of what I want to do:

int fn1(int j){return j;}
int fn2(int j){return j*2;}

class A
{
static virtual int function(int) v = &fn1;

int i;

int get(){return v(i);}       // uses the v of the object calling get.
}

class B : A
{
static virtual int function(int) v = &fn2;
}

the problem comes from the fact that fn1 and fn2 must be part of another
module, therefor they can't be regular members of A & B. This should be
implementable by adding another pointer to the vtbl, I could even live
with a restriction to const pointers.

Is this already doable? Does anyone have any suggested workarounds (this
is used in time critical code)? Does anyone see any problems with this
idea?

I'm not sure what you're tring to achive but the voices are telling me you're overcomplicated. You want something like this, maybe: int fn1(); int fn2(); class A { private: int function() v; public: this() { v = &fn1; } int get() { return v(); } } class B : A { public: this() { v = &fn2; } } If not please explain more and I've try to help you if I can.

Yes that will give the exact functionality I want, however it has a lot of overhead (a pointer in each object, setting that pointer for each object at run time, etc...) Some of this can be removed by adding a function to A, e.i.: int function(int) getV(){return &fn1;} int get(int j){ return getV()(j); } however this adds an extra function call. Hope that disambiguates things.
Dec 21 2005
parent reply Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= <dawid.ciezarkiewicz gmail.com> writes:
BCS wrote:
 I'm not sure what you're tring to achive but the voices are telling me
 you're overcomplicated. You want something like this, maybe:
 
 int fn1();
 int fn2();
 
 class A {
         private:
                 int function() v;
 
         public:
                 this() {
                         v = &fn1;
                 }
 
                 int get() {
                         return v();
                 }
 }
 
 class B : A {
         public:
                 this() {
                         v = &fn2;
                 }
 }
 
 If not please explain more and I've try to help you if I can.

Yes that will give the exact functionality I want, however it has a lot of overhead (a pointer in each object, setting that pointer for each object at run time, etc...) Some of this can be removed by adding a function to A, e.i.: int function(int) getV(){return &fn1;} int get(int j){ return getV()(j); } however this adds an extra function call. Hope that disambiguates things.

Oh! I understand now. One more question. Why can't you just call desired function in overloaded get() (yes, this is more typing but will do what you want without any bloat)? I think you dont have more than 10 classes in that hierachy, but I could miss some reaseons.
Dec 21 2005
parent reply BCS <BCS_member pathlink.com> writes:
Dawid Ciężarkiewicz wrote:
 BCS wrote:
 
I'm not sure what you're tring to achive but the voices are telling me
you're overcomplicated. You want something like this, maybe:

int fn1();
int fn2();

class A {
        private:
                int function() v;

        public:
                this() {
                        v = &fn1;
                }

                int get() {
                        return v();
                }
}

class B : A {
        public:
                this() {
                        v = &fn2;
                }
}

If not please explain more and I've try to help you if I can.

Yes that will give the exact functionality I want, however it has a lot of overhead (a pointer in each object, setting that pointer for each object at run time, etc...) Some of this can be removed by adding a function to A, e.i.: int function(int) getV(){return &fn1;} int get(int j){ return getV()(j); } however this adds an extra function call. Hope that disambiguates things.

Oh! I understand now. One more question. Why can't you just call desired function in overloaded get() (yes, this is more typing but will do what you want without any bloat)? I think you dont have more than 10 classes in that hierachy, but I could miss some reaseons.

The "get" function in the actual case is a rather complicated function that uses the "v" a lot. Overloading that function (get) would introduce the possibility of updating one get without updating the other. I could add a overloaded wrapper but that introduces more overhead.
Dec 21 2005
parent Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= <dawid.ciezarkiewicz gmail.com> writes:
BCS wrote:
 The "get" function in the actual case is a rather complicated function
 that uses the "v" a lot. Overloading that function (get) would introduce
 the possibility of updating one get without updating the other. I could
 add a overloaded wrapper but that introduces more overhead.

_Maybe_ you could use templates/mixins to do that automagicaly. As stand in specs: "Mixins can add virtual functions to a class:". Thats seems to be the best way for you. If not - you'll have to choose which compromise is best.
Dec 22 2005