How use "toHash" without cast

Jonathan M Davis jmdavisProg at gmx.com
Wed Jun 20 18:13:01 PDT 2012


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


More information about the Digitalmars-d-learn mailing list