Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
June 11, 2014 Multiple alias this failed workaround...obscure error message | ||||
---|---|---|---|---|
| ||||
I was looking for a workaround to multiple alias this (or opImplicitCast) the following trick doesn't work (why shouldn't it ?). The error message is quite obscure to me. import std.stdio; class A(Derived) { alias cast(ref Derived)(this).x this; } class B : A!B { float x; } class C : A!C { int x; } void main() { B b; b.x = 0.5; float f; f = b; } output : source/app.d(5): Error: basic type expected, not cast source/app.d(5): Error: no identifier for declarator int source/app.d(5): Error: semicolon expected to close alias declaration source/app.d(5): Error: Declaration expected, not 'cast' Error: DMD compile run failed with exit code 1 |
June 11, 2014 Re: Multiple alias this failed workaround...obscure error message | ||||
---|---|---|---|---|
| ||||
Posted in reply to matovitch | > Sent: Wednesday, June 11, 2014 at 8:07 PM
> From: "matovitch via Digitalmars-d-learn" <digitalmars-d-learn@puremagic.com>
> To: digitalmars-d-learn@puremagic.com
> Subject: Multiple alias this failed workaround...obscure error message
>
> I was looking for a workaround to multiple alias this (or opImplicitCast) the following trick doesn't work (why shouldn't it ?). The error message is quite obscure to me.
>
>
> import std.stdio;
>
> class A(Derived)
> {
> alias cast(ref Derived)(this).x this;
> }
>
> class B : A!B
> {
> float x;
> }
>
> class C : A!C
> {
> int x;
> }
>
> void main()
> {
> B b;
> b.x = 0.5;
>
> float f;
> f = b;
> }
>
>
> output :
>
> source/app.d(5): Error: basic type expected, not cast
> source/app.d(5): Error: no identifier for declarator int
> source/app.d(5): Error: semicolon expected to close alias
> declaration
> source/app.d(5): Error: Declaration expected, not 'cast'
> Error: DMD compile run failed with exit code 1
I don't believe that it's legal to use a cast in an alias declaration, and that's certainly what the error seems to be indicating. Also, using ref in a cast is definitely illegal regardless of where the cast is. ref is not part of a type. The only places that you can use it are function parameters, return types, and foreach variables. If you want to do anything like you seem to be trying to do, you're going to have to alias a function which does the cast for you rather than try and alias the variable itself.
I also don't see anything here that would work as any kind of multiple alias this.
- Jonathan M Davis
|
June 11, 2014 Re: Multiple alias this failed workaround...obscure error message | ||||
---|---|---|---|---|
| ||||
Posted in reply to matovitch | On Wednesday, 11 June 2014 at 18:07:44 UTC, matovitch wrote:
> source/app.d(5): Error: basic type expected, not cast
> source/app.d(5): Error: no identifier for declarator int
> source/app.d(5): Error: semicolon expected to close alias declaration
> source/app.d(5): Error: Declaration expected, not 'cast'
> Error: DMD compile run failed with exit code 1
This particular error stems from the fact that you can only define `alias this` to a symbol, but you are using a cast, which is an expression. For this, a helper function is required:
class A(Derived) {
auto castHelper() {
return (cast(Derived) this).x;
}
}
(Note that you also need to remove the `ref` inside the cast, because classes are already reference types, and the `ref` would mean a reference to a reference.)
But this still doesn't work, as then the compiler crashes while it tries to do the cast, iff the alias this is there. This works:
import std.stdio;
class A(Derived)
{
auto castHelper() {
return (cast(Derived) this).x;
}
//alias castHelper this;
}
class B : A!B
{
float x;
}
class C : A!C
{
int x;
}
void main()
{
auto b = new B;
b.x = 0.5;
auto c = new C;
c.x = 42;
float f = b.castHelper;
writeln("b = ", f);
int i = c.castHelper;
writeln("c = ", i);
}
But if you enable the `alias this` line, it segfaults. You don't even need to reduce the calls to `castHelper` in the main function, it evidently doesn't get that far.
|
June 11, 2014 Re: Multiple alias this failed workaround...obscure error message | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 11 June 2014 at 20:53:21 UTC, Jonathan M Davis via Digitalmars-d-learn wrote:
>
> I don't believe that it's legal to use a cast in an alias declaration, and
> that's certainly what the error seems to be indicating. Also, using ref in a
> cast is definitely illegal regardless of where the cast is. ref is not part
> of a type. The only places that you can use it are function parameters, return
> types, and foreach variables. If you want to do anything like you seem to be
> trying to do, you're going to have to alias a function which does the cast for
> you rather than try and alias the variable itself.
>
> I also don't see anything here that would work as any kind of multiple alias
> this.
>
> - Jonathan M Davis
Thank you, I was assuming D worked as C++ but ref not being part of type is so much better ! (According to Marc Schütz your solution isn't doing so well.)
About alias working with identifier but not with (runtime) expression. Alias should work with compile time expression like map!(x=>2*x) right ? So a static cast should work isn't it ? (though static_cast doesn't exist in D :/)
|
June 11, 2014 Re: Multiple alias this failed workaround...obscure error message | ||||
---|---|---|---|---|
| ||||
Posted in reply to matovitch | If I quote de documentation : "Any casting of a class reference to a derived class reference is done with a runtime check to make sure it really is a downcast. null is the result if it isn't. Note: This is equivalent to the behavior of the dynamic_cast operator in C++." I explicitly kept track of the derived type as template parameter so that the cast could be performed statically (this is absurd :P). |
June 12, 2014 Re: Multiple alias this failed workaround...obscure error message | ||||
---|---|---|---|---|
| ||||
Posted in reply to matovitch | On Wed, 11 Jun 2014 23:01:31 +0000 matovitch via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > About alias working with identifier but not with (runtime) > expression. Alias should work with compile time expression like > map!(x=>2*x) right ? So a static cast should work isn't it ? > (though static_cast doesn't exist in D :/) alias is for _symbols_, not expressions. http://dlang.org/declaration.html#alias I really don't think that what you're trying to do is going to work. - Jonathan M Davis |
Copyright © 1999-2021 by the D Language Foundation