Thread overview | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 28, 2016 Use class template as a type | ||||
---|---|---|---|---|
| ||||
Hi. Is it possible to write in D something like this? ``` abstract class MyClass(T) { public: @property const(T) value(){return _value;} @property void value(T val){_value = val;} ... private: T _value; ... } ... class MyClassFloat: MyClass!float ... class MyClassInt: MyClass!int ... void main() { MyClass[] someArray; someArray ~= new MyClassFloat(); ... someArray ~= new MyClassInt(); ... foreach(myClass; someArray) if(typeid(myClass) == typeid(MyClassInt)) myClass.value = 999; else myClass.value = 123.45f; ... } ``` When I trying to compile code like above I got Error: class MyClass(T) is used as a type. |
November 29, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to dm | In your case I'd just swap out ``MyClass[] someArray;`` to ``Object[] someArray;``. But only because there are no members added without the extra typing in MyClass. Remember types in meta-programming in D are not erased, they exist in the assembly and are unique. Unlike Java who did the implementation rather wrong. |
November 28, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to dm | On Monday, 28 November 2016 at 11:26:41 UTC, dm wrote: > Hi. > Is it possible to write in D something like this? > > ``` > abstract class MyClass(T) > { > public: > @property const(T) value(){return _value;} > @property void value(T val){_value = val;} > ... > private: > T _value; > ... > } > ... > class MyClassFloat: MyClass!float > ... > > class MyClassInt: MyClass!int > ... > > void main() > { > MyClass[] someArray; ---^ > someArray ~= new MyClassFloat(); > ... > > someArray ~= new MyClassInt(); > ... > > foreach(myClass; someArray) > if(typeid(myClass) == typeid(MyClassInt)) > myClass.value = 999; > else > myClass.value = 123.45f; > ... > > } > ``` > When I trying to compile code like above I got > Error: class MyClass(T) is used as a type. Thats because MyClass is a template class. Templates are note types, instansiations of templates can be types. e.g. Myclass!float[] arr; // note this is not MyClass!(float[]); will work. As Rikki suggested using Object[] instead will allow use to store classes of different types. |
November 28, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Monday, 28 November 2016 at 11:30:23 UTC, rikki cattermole wrote:
> In your case I'd just swap out ``MyClass[] someArray;`` to ``Object[] someArray;``.
> But only because there are no members added without the extra typing in MyClass.
>
> Remember types in meta-programming in D are not erased, they exist in the assembly and are unique. Unlike Java who did the implementation rather wrong.
I'm tried to use Object[], but got error
Error: no property 'value' for type 'object.Object'
I guess I must cast() to MyClassInt or MyClassFloat, but how can I do it?
|
November 29, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to dm | On 29/11/2016 2:56 AM, dm wrote:
> On Monday, 28 November 2016 at 11:30:23 UTC, rikki cattermole wrote:
>> In your case I'd just swap out ``MyClass[] someArray;`` to ``Object[]
>> someArray;``.
>> But only because there are no members added without the extra typing
>> in MyClass.
>>
>> Remember types in meta-programming in D are not erased, they exist in
>> the assembly and are unique. Unlike Java who did the implementation
>> rather wrong.
>
> I'm tried to use Object[], but got error
> Error: no property 'value' for type 'object.Object'
> I guess I must cast() to MyClassInt or MyClassFloat, but how can I do it?
We have a handy dandy syntax for this:
if (MyClassInt subclass = cast(MyClassInt)value) {
writeln(subclass.value);
}
If it doesn't cast to said type (it will be null) that branch won't execute.
|
November 28, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | > Thats because MyClass is a template class. Templates are note types, instansiations of templates can be types.
> e.g.
>
> Myclass!float[] arr; // note this is not MyClass!(float[]);
>
> will work. As Rikki suggested using Object[] instead will allow use to store classes of different types.
Maybe I must use some stub class or interface and override all methods...
But I so like D templates, as a result it's a small and easy to understand code.
Or actually it's maybe a XY problem. I'm trying to implement OpenGL material manager and for OpenGL uniforms I tried to write:
```
abstract class Uniform(T)
@property ...
@property ...
T _val;...
void method()...
...
class FloatUniform: Uniform!float
...
override void method()...
And in material class
class Material
...
Texture[] textures;
Uniform[] uniforms;
...
```
Maybe i'm totally wrong and better just use glUniformXXX... in my main app instead of
```
auto uniform = new SomeTypeUniform...
...
uniform.value = someValue;
```
?
|
November 28, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | > We have a handy dandy syntax for this:
>
> if (MyClassInt subclass = cast(MyClassInt)value) {
> writeln(subclass.value);
> }
>
> If it doesn't cast to said type (it will be null) that branch won't execute.
Hell yeah! It's works!
Thank you!
|
November 28, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | > We have a handy dandy syntax for this:
>
> if (MyClassInt subclass = cast(MyClassInt)value) {
> writeln(subclass.value);
> }
>
> If it doesn't cast to said type (it will be null) that branch won't execute.
Just out of interest: it looks like a dynamic_cast in C++ which is considered as slow operation. Is that D cast also a dynamic cast and also slow? I've never used it, so I'm a bit curious.
|
November 29, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 29/11/2016 3:35 AM, Namespace wrote:
>> We have a handy dandy syntax for this:
>>
>> if (MyClassInt subclass = cast(MyClassInt)value) {
>> writeln(subclass.value);
>> }
>>
>> If it doesn't cast to said type (it will be null) that branch won't
>> execute.
>
> Just out of interest: it looks like a dynamic_cast in C++ which is
> considered as slow operation. Is that D cast also a dynamic cast and
> also slow? I've never used it, so I'm a bit curious.
I wouldn't worry about it. You're already using classes and they are dog slow in general.
|
November 29, 2016 Re: Use class template as a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Monday, 28 November 2016 at 14:35:36 UTC, Namespace wrote:
>> We have a handy dandy syntax for this:
>>
>> if (MyClassInt subclass = cast(MyClassInt)value) {
>> writeln(subclass.value);
>> }
>>
>> If it doesn't cast to said type (it will be null) that branch won't execute.
>
> Just out of interest: it looks like a dynamic_cast in C++ which is considered as slow operation. Is that D cast also a dynamic cast and also slow? I've never used it, so I'm a bit curious.
The cast from a class type to a sub class in itself does absolutely nothing. It has only an effect when you call a virtual method. This is slow because of the indirection that happens when the right offset has to be found in the VTBL.
|
Copyright © 1999-2021 by the D Language Foundation