How use "toHash" without cast

Alex Rønne Petersen alex at lycus.org
Wed Jun 20 19:30:32 PDT 2012


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 at lycus.org
http://lycus.org


More information about the Digitalmars-d-learn mailing list