struct Foo {
void bar() {}
void baz() {}
}
void doStuff(Foo foo) {
alias foo.bar fun;
fun(); // Error: need 'this' to access member bar
}
I can't think of any reason why this shouldn't work. foo.bar is a compile-time symbol for the member function Foo.bar() on the instance foo. Once I alias foo.bar to fun, calling fun() should be equivalent to calling foo.bar().
Even if there's some language legalese reason why this shouldn't work according to the spec, it's still a reasonable enhancement request.
Comment #1 by andrej.mitrovich — 2013-02-08T15:36:42Z
*** Issue 7828 has been marked as a duplicate of this issue. ***
Comment #2 by public — 2013-08-06T09:46:54Z
Another application is template alias parameter:
string boo(alias T)()
{
return T.stringof;
}
struct A
{
int field;
}
pragma(msg, boo!(A.field)());
currently this fails with "Error: need 'this' for 'boo' of type 'nothrow @safe string()'" which does not make sense because compile-time usage of symbol "A.field" does not require "this" pointer.
Comment #3 by maxim — 2013-08-06T10:12:00Z
(In reply to comment #0)
> struct Foo {
> void bar() {}
> void baz() {}
> }
>
> void doStuff(Foo foo) {
> alias foo.bar fun;
> fun(); // Error: need 'this' to access member bar
> }
>
Actually error message is reasonable for the same reason as Foo.bar requires this pointer. The root of the issue is that alias does not capture local variable in this context - it captures only type name. The code above is essentially alias Foo.bar fun and since bar() is nonstatic the code doesn't compile.
> I can't think of any reason why this shouldn't work. foo.bar is a compile-time
> symbol for the member function Foo.bar() on the instance foo. Once I alias
> foo.bar to fun, calling fun() should be equivalent to calling foo.bar().
Because of underspecification many view things different to what compiler does.
> Even if there's some language legalese reason why this shouldn't work according
> to the spec, it's still a reasonable enhancement request.
Yes, but this isn't a minor enhancement.
Comment #4 by public — 2013-08-07T06:27:12Z
(In reply to comment #3)
> The root of the issue is that alias does not capture local
> variable in this context - it captures only type name. The code above is
> essentially alias Foo.bar fun and since bar() is nonstatic the code doesn't
> compile.
There is a big issue with `alias` specification because of no clear definition what is captured. Current documentation simply describes behavior of reference implementation in various cases which is rather inconsistent on its own (as far as I am aware, there is no even common alias handling in dmd).
Now my understanding of the `alias` concept is simple - it should capture symbols, be it type symbol or variable symbol or anonymous lambda literal symbol.
But I think you are right - cleaning this is worth separate DIP, plenty of corner cases will arise.
Comment #5 by richard.sams — 2016-01-04T19:48:03Z
Maybe the same Problem, i want to alias a function name + instance global :
import std.stdio;
public import std.experimental.logger;
alias Warning = Log.Warning1;//ERROR:Not working!?
FLog Log;
shared static this () { Log = new FLog("Test.log");}
class FLog : FileLogger
{
this(string newName) @safe
{
super(newName, LogLevel.info);
Warning("Try "); //Alias ----------- OK -----------------
}
///Name hiding! ok
alias Warning = super.warningf;
//General log Warning Message
void Warning1(string message)
{
try{super.warning(message);}
catch(Exception e){}
}
}
int main(string[] argv)
{
Warning("Try "); //Alias -------------- Fail ------------------
//works if Warning1 is static . . . but then super is not allowed
Log.Warning1("Try ");//OK
Log.Warning("Try ");//OK
return 0;
}
Comment #6 by robert.schadek — 2024-12-13T17:50:48Z