www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Static function template

reply "Lemonfiend" <lemon fie.nd> writes:
Is it not possible to have a static function template with the 
same name as the non-static version?

struct S
{
     int i;

     auto foo(T)(int j) {
         i=j;
     }

     static auto foo(T)(int j) {
         S s;
         s.foo!T(j);
         return s;
     }
}

void main()
{
     auto s = S.foo!bool(1);
}

Error: need 'this' for 'foo' of type '(int j)'
May 07 2015
next sibling parent Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
On Thu, 07 May 2015 10:19:42 +0000
Lemonfiend via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 Is it not possible to have a static function template with the 
 same name as the non-static version?
 
 struct S
 {
      int i;
 
      auto foo(T)(int j) {
          i=j;
      }
 
      static auto foo(T)(int j) {
          S s;
          s.foo!T(j);
          return s;
      }
 }
 
 void main()
 {
      auto s = S.foo!bool(1);
 }
 
 Error: need 'this' for 'foo' of type '(int j)'
It is not. You can't even have same name for field and method: struct S { int s; void s() { do_something(); } } test.d(8): Error: function test.S.s conflicts with variable test.S.s at test.d(7) And this make sense
May 07 2015
prev sibling next sibling parent reply "Vadim Lopatin" <coolreader.org gmail.com> writes:
On Thursday, 7 May 2015 at 10:19:44 UTC, Lemonfiend wrote:
 Is it not possible to have a static function template with the 
 same name as the non-static version?

 struct S
 {
     int i;

     auto foo(T)(int j) {
         i=j;
     }

     static auto foo(T)(int j) {
         S s;
         s.foo!T(j);
         return s;
     }
 }

 void main()
 {
     auto s = S.foo!bool(1);
 }

 Error: need 'this' for 'foo' of type '(int j)'
Can be fixed by using of different names for static and non-static function. Not sure why doesn't work w/o this change (compiler bug?) struct S { int i; auto foo2(T)(int j) { i=j; } static S foo(T)(int j) { S s; s.foo2!T(j); return s; } } void main() { auto s = S.foo!bool(1); }
May 07 2015
parent reply Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
On Thu, 07 May 2015 10:33:44 +0000
Vadim Lopatin via Digitalmars-d-learn
<digitalmars-d-learn puremagic.com> wrote:

 struct S
 {
      int i;
 
      auto foo2(T)(int j) {
          i=j;
      }
 
      static S foo(T)(int j) {
          S s;
          s.foo2!T(j);
          return s;
      }
 }
 
 void main()
 {
      auto s = S.foo!bool(1);
 }
As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases.
May 07 2015
parent reply "Daniel Kozak" <kozzi11 gmail.com> writes:
On Thursday, 7 May 2015 at 10:39:09 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:33:44 +0000
 Vadim Lopatin via Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:

 struct S
 {
      int i;
 
      auto foo2(T)(int j) {
          i=j;
      }
 
      static S foo(T)(int j) {
          S s;
          s.foo2!T(j);
          return s;
      }
 }
 
 void main()
 {
      auto s = S.foo!bool(1);
 }
As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases.
e.g.: import std.stdio; struct S { string foo = "Please select me?"; string foo() { return ("No, select me?"); }; static string foo() { return ("I am better than the otters :D?"); }; } void main() { auto s = S(); writeln(s.foo); }
May 07 2015
parent reply "Lemonfiend" <lemon fie.nd> writes:
On Thursday, 7 May 2015 at 10:43:28 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 10:39:09 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:33:44 +0000
 Vadim Lopatin via Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:

 struct S
 {
     int i;
 
     auto foo2(T)(int j) {
         i=j;
     }
 
     static S foo(T)(int j) {
         S s;
         s.foo2!T(j);
         return s;
     }
 }
 
 void main()
 {
     auto s = S.foo!bool(1);
 }
As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases.
e.g.: import std.stdio; struct S { string foo = "Please select me?"; string foo() { return ("No, select me?"); }; static string foo() { return ("I am better than the otters :D?"); }; } void main() { auto s = S(); writeln(s.foo); }
Well it's clear to me now why it shouldn't work. However, the error msg is not clear on the problem. Imo it should give a conflict error like in your previous example. That would make it clear what's happened/allowed. The current error seemed like it matched the wrong template, prompting me to look for a buggy function template implementation.
May 07 2015
parent reply Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
On Thu, 07 May 2015 10:46:19 +0000
Lemonfiend via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 On Thursday, 7 May 2015 at 10:43:28 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 10:39:09 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:33:44 +0000
 Vadim Lopatin via Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:

 struct S
 {
     int i;
 
     auto foo2(T)(int j) {
         i=j;
     }
 
     static S foo(T)(int j) {
         S s;
         s.foo2!T(j);
         return s;
     }
 }
 
 void main()
 {
     auto s = S.foo!bool(1);
 }
As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases.
e.g.: import std.stdio; struct S { string foo = "Please select me?"; string foo() { return ("No, select me?"); }; static string foo() { return ("I am better than the otters :D?"); }; } void main() { auto s = S(); writeln(s.foo); }
Well it's clear to me now why it shouldn't work. However, the error msg is not clear on the problem. Imo it should give a conflict error like in your previous example. That would make it clear what's happened/allowed.
Yep, I think you are right even this example make useless and wrong error message: struct S { static S foo(T)(int j) { S s; return s; } static S foo(T)(int j) { S s; return s; } } void main() { auto s = S.foo!bool(1); } test.d(15): Error: need 'this' for 'foo' of type '(int j)' // WTF?
May 07 2015
parent reply "Daniel Kozak" <kozzi11 gmail.com> writes:
On Thursday, 7 May 2015 at 11:08:50 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:46:19 +0000
 Lemonfiend via Digitalmars-d-learn 
 <digitalmars-d-learn puremagic.com>
 wrote:

 On Thursday, 7 May 2015 at 10:43:28 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 10:39:09 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:33:44 +0000
 Vadim Lopatin via Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:

 struct S
 {
     int i;
 
     auto foo2(T)(int j) {
         i=j;
     }
 
     static S foo(T)(int j) {
         S s;
         s.foo2!T(j);
         return s;
     }
 }
 
 void main()
 {
     auto s = S.foo!bool(1);
 }
As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases.
e.g.: import std.stdio; struct S { string foo = "Please select me?"; string foo() { return ("No, select me?"); }; static string foo() { return ("I am better than the otters :D?"); }; } void main() { auto s = S(); writeln(s.foo); }
Well it's clear to me now why it shouldn't work. However, the error msg is not clear on the problem. Imo it should give a conflict error like in your previous example. That would make it clear what's happened/allowed.
Yep, I think you are right even this example make useless and wrong error message: struct S { static S foo(T)(int j) { S s; return s; } static S foo(T)(int j) { S s; return s; } } void main() { auto s = S.foo!bool(1); } test.d(15): Error: need 'this' for 'foo' of type '(int j)' // WTF?
btw. it is a regresion from 2.067 on 2.066 and before it makes much better error. Even for OP code when is modified (static must be declared before non static one) it have a better error msg. test.d(6): Error: test.S.foo called with argument types (int) matches both: test.d(4): test.S.foo!bool.foo(int j) and: test.d(10): test.S.foo!bool.foo(int j) test.d(18): Error: template instance test.S.foo!bool error instantiating But only when static one is declared before non static one, so even on 2.066 it was not ideal. So I think we should open two issues, probably one for regression and one for enhancment
May 07 2015
parent reply "Daniel Kozak" <kozzi11 gmail.com> writes:
On Thursday, 7 May 2015 at 11:15:02 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 11:08:50 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:46:19 +0000
 Lemonfiend via Digitalmars-d-learn 
 <digitalmars-d-learn puremagic.com>
 wrote:

 On Thursday, 7 May 2015 at 10:43:28 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 10:39:09 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:33:44 +0000
 Vadim Lopatin via Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:

 struct S
 {
    int i;
 
    auto foo2(T)(int j) {
        i=j;
    }
 
    static S foo(T)(int j) {
        S s;
        s.foo2!T(j);
        return s;
    }
 }
 
 void main()
 {
    auto s = S.foo!bool(1);
 }
As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases.
e.g.: import std.stdio; struct S { string foo = "Please select me?"; string foo() { return ("No, select me?"); }; static string foo() { return ("I am better than the otters :D?"); }; } void main() { auto s = S(); writeln(s.foo); }
Well it's clear to me now why it shouldn't work. However, the error msg is not clear on the problem. Imo it should give a conflict error like in your previous example. That would make it clear what's happened/allowed.
Yep, I think you are right even this example make useless and wrong error message: struct S { static S foo(T)(int j) { S s; return s; } static S foo(T)(int j) { S s; return s; } } void main() { auto s = S.foo!bool(1); } test.d(15): Error: need 'this' for 'foo' of type '(int j)' // WTF?
btw. it is a regresion from 2.067 on 2.066 and before it makes much better error. Even for OP code when is modified (static must be declared before non static one) it have a better error msg. test.d(6): Error: test.S.foo called with argument types (int) matches both: test.d(4): test.S.foo!bool.foo(int j) and: test.d(10): test.S.foo!bool.foo(int j) test.d(18): Error: template instance test.S.foo!bool error instantiating But only when static one is declared before non static one, so even on 2.066 it was not ideal. So I think we should open two issues, probably one for regression and one for enhancment
OK both are regressions, cause on dmd 2.063 it is much much better test.d(19): Error: template test.S.foo matches more than one template declaration, test.d(3):foo(T)(int j) and test.d(8):foo(T)(int j) test.d(19): Error: need 'this' for 'foo' of type 'pure nothrow safe void(int j)'
May 07 2015
parent "Daniel Kozak" <kozzi11 gmail.com> writes:
On Thursday, 7 May 2015 at 11:18:17 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 11:15:02 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 11:08:50 UTC, Daniel Kozák wrote:
 On Thu, 07 May 2015 10:46:19 +0000
 Lemonfiend via Digitalmars-d-learn 
 <digitalmars-d-learn puremagic.com>
 wrote:

 On Thursday, 7 May 2015 at 10:43:28 UTC, Daniel Kozak wrote:
 On Thursday, 7 May 2015 at 10:39:09 UTC, Daniel Kozák 
 wrote:
 On Thu, 07 May 2015 10:33:44 +0000
 Vadim Lopatin via Digitalmars-d-learn
 <digitalmars-d-learn puremagic.com> wrote:

 struct S
 {
   int i;
 
   auto foo2(T)(int j) {
       i=j;
   }
 
   static S foo(T)(int j) {
       S s;
       s.foo2!T(j);
       return s;
   }
 }
 
 void main()
 {
   auto s = S.foo!bool(1);
 }
As I said, it is not bug. It is OK. There is no way how you can distinguish between static and non static methods or even field in some cases.
e.g.: import std.stdio; struct S { string foo = "Please select me?"; string foo() { return ("No, select me?"); }; static string foo() { return ("I am better than the otters :D?"); }; } void main() { auto s = S(); writeln(s.foo); }
Well it's clear to me now why it shouldn't work. However, the error msg is not clear on the problem. Imo it should give a conflict error like in your previous example. That would make it clear what's happened/allowed.
Yep, I think you are right even this example make useless and wrong error message: struct S { static S foo(T)(int j) { S s; return s; } static S foo(T)(int j) { S s; return s; } } void main() { auto s = S.foo!bool(1); } test.d(15): Error: need 'this' for 'foo' of type '(int j)' // WTF?
btw. it is a regresion from 2.067 on 2.066 and before it makes much better error. Even for OP code when is modified (static must be declared before non static one) it have a better error msg. test.d(6): Error: test.S.foo called with argument types (int) matches both: test.d(4): test.S.foo!bool.foo(int j) and: test.d(10): test.S.foo!bool.foo(int j) test.d(18): Error: template instance test.S.foo!bool error instantiating But only when static one is declared before non static one, so even on 2.066 it was not ideal. So I think we should open two issues, probably one for regression and one for enhancment
OK both are regressions, cause on dmd 2.063 it is much much better test.d(19): Error: template test.S.foo matches more than one template declaration, test.d(3):foo(T)(int j) and test.d(8):foo(T)(int j) test.d(19): Error: need 'this' for 'foo' of type 'pure nothrow safe void(int j)'
https://issues.dlang.org/show_bug.cgi?id=14554
May 07 2015
prev sibling next sibling parent Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
On Thu, 07 May 2015 10:19:42 +0000
Lemonfiend via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 Is it not possible to have a static function template with the 
 same name as the non-static version?
 
 struct S
 {
      int i;
 
      auto foo(T)(int j) {
          i=j;
      }
 
      static auto foo(T)(int j) {
          S s;
          s.foo!T(j);
          return s;
      }
 }
 
 void main()
 {
      auto s = S.foo!bool(1);
 }
 
 Error: need 'this' for 'foo' of type '(int j)'
Btw. you can use s.foo even for static: struct S { int i; static auto foo(T)(int j) { S s; s.i = j; return s; } } void main() { auto s = S(); s = s.foo!bool(1); writeln(s); }
May 07 2015
prev sibling next sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Thursday, May 07, 2015 10:19:42 Lemonfiend via Digitalmars-d-learn wrote:
 Is it not possible to have a static function template with the
 same name as the non-static version?
No. Unfortunately, you can't overload based on static. I believe that it works if they're overloaded on parameters but not based on static. It's probably in order to avoid function hijacking in cases like this: S s; s.foo(); since unfortunately, that call syntax works whether foo is static or not. I think that it would be much better if you had to call it via the type and that calling via an instance wouldn't be legal, but it is legal. And given that fact, overloading based on static would arguably be a bad idea. - Jonathan M Davis
May 07 2015
prev sibling parent "Daniel Kozak" <kozzi11 gmail.com> writes:
On Thursday, 7 May 2015 at 10:19:44 UTC, Lemonfiend wrote:
 Is it not possible to have a static function template with the 
 same name as the non-static version?

 struct S
 {
     int i;

     auto foo(T)(int j) {
         i=j;
     }

     static auto foo(T)(int j) {
         S s;
         s.foo!T(j);
         return s;
     }
 }

 void main()
 {
     auto s = S.foo!bool(1);
 }

 Error: need 'this' for 'foo' of type '(int j)'
Another thinks which is wierd is than on 2.066 it prints: test.d(17): Error: need 'this' for 'foo' of type 'pure nothrow nogc safe void(int j)' So it seems auto deduction for attributes does not work anymore :( (in this case I guess)
May 07 2015