Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
June 20, 2012 How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
hello, iI have written a template vector class. Now I need to rewrite the tohash function in dependence to the coords. But i have no clue because it doesn't allow any casts or convertions, because its a @trusted method. Because of that i cannot override toHash for float, real or double. Any ideas? |
June 20, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 21-06-2012 00:31, Namespace wrote: > hello, iI have written a template vector class. Now I need to rewrite > the tohash function in dependence to the coords. But i have no clue > because it doesn't allow any casts or convertions, because its a > @trusted method. > Because of that i cannot override toHash for float, real or double. > Any ideas? I don't really understand the problem. I think you need to show some code. @trusted doesn't actually affect whether you can cast or convert anything. -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
June 20, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | That is my Code: [code] class Vector2D(T) { private: static Vector2D!(T) CastFromObject(Object o) { import std.typetuple; foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real)) { if (auto vec = cast(Vector2D!(Type)) o) { return cast(Vector2D!(T)) vec; } } return null; } public: T x; T y; this(T x, T y) { this.x = x; this.y = y; } static Vector2D!(T) opCall(T x, T y) { return new Vector2D!(T)(x, y); } float Summe() const pure nothrow { return this.x + this.y; } override bool opEquals(Object o) const { if (o is null) { debug { writeln("Object is null ;)"); } return false; } const Vector2D!(T) vec = CastFromObject(o); if (vec is this) { return true; } return (vec.x == this.x) && (vec.y == this.y); } override hash_t toHash() const pure nothrow { return this.x + this.y; } override int opCmp(Object o) const { if (o is null) { return -1; } const Vector2D vec = CastFromObject(o); if (vec is this) { return 0; } if (this.Summe() > vec.Summe()) { return 1; } if (this.Summe() < vec.Summe()) { return -1; } return 0; } override string toString() const { return "Vector2D!(" ~ T.stringof ~ ")(" ~ to!(string)(this.x) ~ ", " ~ to!(string)(this.y) ~ ")"; } } [/code] I have dmd 2.059 and with my current version of toHash i get the compiler errors, that he cannot implicit convert from float, real, double, long and so on to uint. I cannot solve the problem with a simple cast or to!uint because then he said that casts form float to uint are not allowed or that to! isn't trusted and nothrow. I hate such annoying errors... |
June 21, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Thursday, June 21, 2012 00:43:49 Namespace wrote:
> That is my Code:
>
> [code]
> class Vector2D(T) {
> private:
> static Vector2D!(T) CastFromObject(Object o) {
> import std.typetuple;
>
> foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int,
> uint, long, ulong, float, double, real)) {
> if (auto vec = cast(Vector2D!(Type)) o) {
> return cast(Vector2D!(T)) vec;
> }
> }
>
> return null;
> }
>
> public:
> T x;
> T y;
>
> this(T x, T y) {
> this.x = x;
> this.y = y;
> }
>
> static Vector2D!(T) opCall(T x, T y) {
> return new Vector2D!(T)(x, y);
> }
>
> float Summe() const pure nothrow {
> return this.x + this.y;
> }
>
> override bool opEquals(Object o) const {
> if (o is null) {
> debug {
> writeln("Object is null ;)");
> }
>
> return false;
> }
>
> const Vector2D!(T) vec = CastFromObject(o);
>
> if (vec is this) {
> return true;
> }
>
> return (vec.x == this.x) && (vec.y == this.y);
> }
>
> override hash_t toHash() const pure nothrow {
> return this.x + this.y;
> }
>
> override int opCmp(Object o) const {
> if (o is null) {
> return -1;
> }
>
> const Vector2D vec = CastFromObject(o);
>
> if (vec is this) {
> return 0;
> }
>
> if (this.Summe() > vec.Summe()) {
> return 1;
> }
>
> if (this.Summe() < vec.Summe()) {
> return -1;
> }
>
> return 0;
> }
>
> override string toString() const {
> return "Vector2D!(" ~ T.stringof ~ ")(" ~ to!(string)(this.x) ~
> ", " ~ to!(string)(this.y) ~ ")";
> }
> }
>
> [/code]
>
> I have dmd 2.059 and with my current version of toHash i get the
> compiler errors, that he cannot implicit convert from float,
> real, double, long and so on to uint.
> I cannot solve the problem with a simple cast or to!uint because
> then he said that casts form float to uint are not allowed or
> that to! isn't trusted and nothrow. I hate such annoying errors...
Eventually, toHash will have to be @safe const pure nothrow, but I don't think that the compiler requires that yet (though work was being done on that, so it may). You didn't mark toHash as @safe though, so it may be inferring it from Object (I believe that it _has_ been changed so that attributes are now inferred from the base class declarations when overriding). So, toHash may be being inferred as @safe. Try marking toHash as @trusted. If that doesn't work, then move its implementation into another function which you mark as @trusted and have toHash call it (since @safe can call @trusted but can't do @system stuff, unlike @trusted).
- Jonathan M Davis
|
June 21, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 21-06-2012 03:13, Jonathan M Davis wrote: > On Thursday, June 21, 2012 00:43:49 Namespace wrote: >> That is my Code: >> >> [code] >> class Vector2D(T) { >> private: >> static Vector2D!(T) CastFromObject(Object o) { >> import std.typetuple; >> >> foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int, >> uint, long, ulong, float, double, real)) { >> if (auto vec = cast(Vector2D!(Type)) o) { >> return cast(Vector2D!(T)) vec; >> } >> } >> >> return null; >> } >> >> public: >> T x; >> T y; >> >> this(T x, T y) { >> this.x = x; >> this.y = y; >> } >> >> static Vector2D!(T) opCall(T x, T y) { >> return new Vector2D!(T)(x, y); >> } >> >> float Summe() const pure nothrow { >> return this.x + this.y; >> } >> >> override bool opEquals(Object o) const { >> if (o is null) { >> debug { >> writeln("Object is null ;)"); >> } >> >> return false; >> } >> >> const Vector2D!(T) vec = CastFromObject(o); >> >> if (vec is this) { >> return true; >> } >> >> return (vec.x == this.x)&& (vec.y == this.y); >> } >> >> override hash_t toHash() const pure nothrow { >> return this.x + this.y; >> } >> >> override int opCmp(Object o) const { >> if (o is null) { >> return -1; >> } >> >> const Vector2D vec = CastFromObject(o); >> >> if (vec is this) { >> return 0; >> } >> >> if (this.Summe()> vec.Summe()) { >> return 1; >> } >> >> if (this.Summe()< vec.Summe()) { >> return -1; >> } >> >> return 0; >> } >> >> override string toString() const { >> return "Vector2D!(" ~ T.stringof ~ ")(" ~ to!(string)(this.x) ~ >> ", " ~ to!(string)(this.y) ~ ")"; >> } >> } >> >> [/code] >> >> I have dmd 2.059 and with my current version of toHash i get the >> compiler errors, that he cannot implicit convert from float, >> real, double, long and so on to uint. >> I cannot solve the problem with a simple cast or to!uint because >> then he said that casts form float to uint are not allowed or >> that to! isn't trusted and nothrow. I hate such annoying errors... > > Eventually, toHash will have to be @safe const pure nothrow, but I don't think > that the compiler requires that yet (though work was being done on that, so it > may). You didn't mark toHash as @safe though, so it may be inferring it from > Object (I believe that it _has_ been changed so that attributes are now > inferred from the base class declarations when overriding). So, toHash may be > being inferred as @safe. Try marking toHash as @trusted. If that doesn't work, > then move its implementation into another function which you mark as @trusted > and have toHash call it (since @safe can call @trusted but can't do @system > stuff, unlike @trusted). > > - Jonathan M Davis It's actually @trusted as per the docs. I do not know why DMD infers that to be @safe..... In any case, the solution here is this: override hash_t toHash() @trusted const pure nothrow { return cast(hash_t)(this.x + this.y); } -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
June 21, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On 21-06-2012 04:30, Alex Rønne Petersen wrote: > On 21-06-2012 03:13, Jonathan M Davis wrote: >> On Thursday, June 21, 2012 00:43:49 Namespace wrote: >>> That is my Code: >>> >>> [code] >>> class Vector2D(T) { >>> private: >>> static Vector2D!(T) CastFromObject(Object o) { >>> import std.typetuple; >>> >>> foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int, >>> uint, long, ulong, float, double, real)) { >>> if (auto vec = cast(Vector2D!(Type)) o) { >>> return cast(Vector2D!(T)) vec; >>> } >>> } >>> >>> return null; >>> } >>> >>> public: >>> T x; >>> T y; >>> >>> this(T x, T y) { >>> this.x = x; >>> this.y = y; >>> } >>> >>> static Vector2D!(T) opCall(T x, T y) { >>> return new Vector2D!(T)(x, y); >>> } >>> >>> float Summe() const pure nothrow { >>> return this.x + this.y; >>> } >>> >>> override bool opEquals(Object o) const { >>> if (o is null) { >>> debug { >>> writeln("Object is null ;)"); >>> } >>> >>> return false; >>> } >>> >>> const Vector2D!(T) vec = CastFromObject(o); >>> >>> if (vec is this) { >>> return true; >>> } >>> >>> return (vec.x == this.x)&& (vec.y == this.y); >>> } >>> >>> override hash_t toHash() const pure nothrow { >>> return this.x + this.y; >>> } >>> >>> override int opCmp(Object o) const { >>> if (o is null) { >>> return -1; >>> } >>> >>> const Vector2D vec = CastFromObject(o); >>> >>> if (vec is this) { >>> return 0; >>> } >>> >>> if (this.Summe()> vec.Summe()) { >>> return 1; >>> } >>> >>> if (this.Summe()< vec.Summe()) { >>> return -1; >>> } >>> >>> return 0; >>> } >>> >>> override string toString() const { >>> return "Vector2D!(" ~ T.stringof ~ ")(" ~ to!(string)(this.x) ~ >>> ", " ~ to!(string)(this.y) ~ ")"; >>> } >>> } >>> >>> [/code] >>> >>> I have dmd 2.059 and with my current version of toHash i get the >>> compiler errors, that he cannot implicit convert from float, >>> real, double, long and so on to uint. >>> I cannot solve the problem with a simple cast or to!uint because >>> then he said that casts form float to uint are not allowed or >>> that to! isn't trusted and nothrow. I hate such annoying errors... >> >> Eventually, toHash will have to be @safe const pure nothrow, but I >> don't think >> that the compiler requires that yet (though work was being done on >> that, so it >> may). You didn't mark toHash as @safe though, so it may be inferring >> it from >> Object (I believe that it _has_ been changed so that attributes are now >> inferred from the base class declarations when overriding). So, toHash >> may be >> being inferred as @safe. Try marking toHash as @trusted. If that >> doesn't work, >> then move its implementation into another function which you mark as >> @trusted >> and have toHash call it (since @safe can call @trusted but can't do >> @system >> stuff, unlike @trusted). >> >> - Jonathan M Davis > > It's actually @trusted as per the docs. I do not know why DMD infers > that to be @safe..... > > In any case, the solution here is this: > > override hash_t toHash() @trusted const pure nothrow { > return cast(hash_t)(this.x + this.y); > } > Filed a bug: http://d.puremagic.com/issues/show_bug.cgi?id=8275 -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
June 21, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | > It's actually @trusted as per the docs. I do not know why DMD infers that to be @safe.....
>
> In any case, the solution here is this:
>
> override hash_t toHash() @trusted const pure nothrow {
> return cast(hash_t)(this.x + this.y);
> }
Yes, it's already trusted.
If I write "@trusted const pure nothrow" it works fine, but if i write "const pure nothrow" not. Why? I thought the compiler is orientating at the base method which is overriden.
|
June 21, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Thursday, June 21, 2012 09:48:52 Namespace wrote: > > It's actually @trusted as per the docs. I do not know why DMD infers that to be @safe..... > > > > In any case, the solution here is this: > > override hash_t toHash() @trusted const pure nothrow { > > > > return cast(hash_t)(this.x + this.y); > > > > } > > Yes, it's already trusted. > > If I write "@trusted const pure nothrow" it works fine, but if i write "const pure nothrow" not. Why? I thought the compiler is orientating at the base method which is overriden. Apparently, when you override an @trusted method, the method in the derived class is inferred to be @safe - which makes sense when you think about it, since the derived class' function hasn't done anything @system. If it calls the base class' version, which is @trusted, then it can be @safe. So, as long as it doesn't do anything @system itself, it can be @safe. However, since the compiler doesn't infer any attributes from the derived class' function's body (since it's not templated), if you do any @system stuff in there, it'll give you a compilation error rather than treating it as @system - though that makes sense too, since having a derived class function with worse guarantees than a base class function isn't valid. So, even if the attributes _were_ inferred from the function's body, it would _still_ have to give you an error, since the body would be @system when it needed to be at least @trusted. http://d.puremagic.com/issues/show_bug.cgi?id=8275 - Jonathan M Davis |
June 21, 2012 Re: How use "toHash" without cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | I see, a bit confusing but I think I understand. Thank you. :) |
Copyright © 1999-2021 by the D Language Foundation