Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 02, 2017 Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Hey, wondering whether it's possible to access the derived type from a function template in the base class or interface. this T does not seem to be working, I guess because it's a static function and this does not exists?! interface I { static void test(this T)() { writeln(T.type.stringof); } } abstract class A { static void test(this T)() { writeln(T.type.stringof); } } class B : A { alias type = uint; } class C : I { alias type = int; } void main() { B.test(); C.test(); } Throws: Error: template app.A.test cannot deduce function from argument types !()(), candidates are: app.A.test(this T)() Error: template app.I.test cannot deduce function from argument types !()(), candidates are: app.I.test(this T)() Any way I could accomplish this? |
August 02, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On 8/2/17 8:07 AM, Timoses wrote: > Hey, > > wondering whether it's possible to access the derived type from a function template in the base class or interface. > > this T does not seem to be working, I guess because it's a static function and this does not exists?! Yep. > Any way I could accomplish this? Move test outside the interface: void test(C)(C c) if(is(C : I)) { writeln(C.type.stringof); } Though, at that point, you don't need I. I'm assuming you have a more complex real-world example. -Steve |
August 02, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 2 August 2017 at 12:49:12 UTC, Steven Schveighoffer wrote:
> On 8/2/17 8:07 AM, Timoses wrote:
>> Hey,
>>
>> wondering whether it's possible to access the derived type from a function template in the base class or interface.
>>
>> this T does not seem to be working, I guess because it's a static function and this does not exists?!
>
> Yep.
>
>> Any way I could accomplish this?
>
> Move test outside the interface:
>
> void test(C)(C c) if(is(C : I))
> {
> writeln(C.type.stringof);
> }
>
> Though, at that point, you don't need I. I'm assuming you have a more complex real-world example.
>
> -Steve
Thanks for the reply!
Not sure I understand correctly, though.
interface I {}
class A : I {}
void test(T)(T t) if(is(T: I))
{ writeln(T.type.stringof); }
void main()
{
A.test;
}
throws:
Error: no property 'test' for type 'app.A'
which it of course does... test(A) makes no sense either.
I need to call it statically and want to know the derived class type in the base class (or interface) function template.
Is there a trick in your answer? : P
|
August 02, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On 08/02/2017 02:07 PM, Timoses wrote: > Hey, > > wondering whether it's possible to access the derived type from a function template in the base class or interface. > > this T does not seem to be working, I guess because it's a static function and this does not exists?! > > [...] > > Any way I could accomplish this? Well, it's a clumsy workaround, but the only thing missing seems to be the "this T" automatic deduction. I was recently hit by something similar: the "this" parameter deduction only works for instance methods. It was not totally clear if it was a bug or a feature... The documentation [1] is however quite clear: > TemplateThisParameters are used in member function templates to pick up the type of the this reference. So, static functions doesn't seem to be covered. You can, however, make it explicit: ``` B.test!B(); C.test!C(); ``` And then even alias it to prevent accidental mismatches: ``` import std.stdio; interface I { static void test(this T)() { writeln(T.type.stringof); } } abstract class A { static void test(this T)() { writeln(T.type.stringof); } } class B : A { alias type = uint; } class C : I { alias type = int; } void main() { test!B(); test!C(); } alias test(T) = T.test!T; ``` [1]: http://dlang.org/spec/template.html#TemplateThisParameter |
August 02, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On 8/2/17 9:11 AM, Timoses wrote:
> On Wednesday, 2 August 2017 at 12:49:12 UTC, Steven Schveighoffer wrote: Thanks for the reply!
>
> Not sure I understand correctly, though.
>
> interface I {}
> class A : I {}
>
> void test(T)(T t) if(is(T: I))
> { writeln(T.type.stringof); }
>
> void main()
> {
> A.test;
> }
>
> throws:
> Error: no property 'test' for type 'app.A'
>
> which it of course does... test(A) makes no sense either.
> I need to call it statically and want to know the derived class type in the base class (or interface) function template.
>
> Is there a trick in your answer? : P
Sorry, I didn't read your original post thoroughly, you need an instance to make this work properly.
A a;
a.test; // should work
What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features.
However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter.
-Steve
|
August 02, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | > > What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features. > Well, there are interesting things to do: https://dpaste.dzfl.pl/ed826ae21473 I don't know if that's what one would call "virtual static", but I'd say it comes close... |
August 02, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arafel | Thanks Arafel, the alias workaround might just be a nice way to put it. On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote: > What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features. I'm not looking to overwrite the static method (which would refer to virtual, right?). The solution I had previously was: interface I { static void test(T)() { writeln(T.stringof); } } class B : I { alias type = int; static void test() { I.test!type(); } } void main() { B.test(); } However, this requires to add the base type as in I.test!type(); otherwise (only test!type();) it complains about Error: template instance test!type test is not a template declaration, it is a function I was hoping there was a way to simply define it in the base class/interface without producing redundant code in each derived class. Arafel's solution gets very close! On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote: > However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter. I guess the `this` is really misleading it being a static method. I suppose https://issues.dlang.org/buglist.cgi?bug_severity=enhancement&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=D&query_format=report-table&y_axis_field=bug_severity would be the place for an enhancement request? Possibly related: https://issues.dlang.org/show_bug.cgi?id=14191 On Wednesday, 2 August 2017 at 14:23:26 UTC, Arafel wrote: > >> >> What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features. >> > > Well, there are interesting things to do: > > https://dpaste.dzfl.pl/ed826ae21473 > > I don't know if that's what one would call "virtual static", but I'd say it comes close... Nifty, but still doesn't allow knowing the derived type B in the foo method of A, does it? |
August 02, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On 8/2/17 11:06 AM, Timoses wrote:
> On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote:
>> However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter.
>
> I guess the `this` is really misleading it being a static method.
> I suppose https://issues.dlang.org/buglist.cgi?bug_severity=enhancement&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=D&query_format=report-table&y_axis_field=bug_severity would be the place for an enhancement request?
> Possibly related:
> https://issues.dlang.org/show_bug.cgi?id=14191
Yes, that's exactly it.
Note that typeof(this) has special meaning for static methods:
class C
{
static typeof(this) foo() { return new typeof(this); }
}
So there is precedence for the meaning of `this` in a static context.
-Steve
|
August 03, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On Wednesday, 2 August 2017 at 12:07:46 UTC, Timoses wrote: > Hey, > > wondering whether it's possible to access the derived type from a function template in the base class or interface. > > [...] Created an enhancement issue: https://issues.dlang.org/show_bug.cgi?id=17714 |
August 03, 2017 Re: Access derived type in baseclass static function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 2 August 2017 at 15:38:12 UTC, Steven Schveighoffer wrote:
> On 8/2/17 11:06 AM, Timoses wrote:
>> On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote:
>>> However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter.
>>
>> I guess the `this` is really misleading it being a static method.
>> I suppose https://issues.dlang.org/buglist.cgi?bug_severity=enhancement&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=D&query_format=report-table&y_axis_field=bug_severity would be the place for an enhancement request?
>> Possibly related:
>> https://issues.dlang.org/show_bug.cgi?id=14191
>
> Yes, that's exactly it.
>
> Note that typeof(this) has special meaning for static methods:
>
> class C
> {
> static typeof(this) foo() { return new typeof(this); }
> }
>
> So there is precedence for the meaning of `this` in a static context.
>
> -Steve
Oh, just now get it after creating the issue ^^. Makes sense. I kind of connected the "this" to existing instances because the DMD compiler often complains about something like "need this for..." when calling something from a static method that... well... needs "this" or instantiation..
E.g.:
class A
{
static void a()
{
b();
}
void b();
}
will throw
Error: need 'this' for 'b' of type 'void()'
|
Copyright © 1999-2021 by the D Language Foundation