d重载操作符

原文

不要在你的opBinary上返回ref.你不能通过ref返回新事物,只能返回成员变量.所以取下ref并替换其为auto.然后编译.

auto opBinary(string op, Rhs : meter!(otherValueT), otherValueT) (in Rhs rhs)

代码:

//长度
struct Length(T) {
    /// 不要直接构建.
    private this(T t) { value = t; }

    T value;
}

/// 特定单元长度
struct meters(T) {
    /// 实际存储.
    private Length!T value;

    Length!T getValue() {
        return value;
    }

    /// 通过属性隐式转换
    alias getValue this;

    ///用基本类型构造
    this(T t) {
        value.value = t * 100; // 1米为100cm.
    }

    /// 用已有来构造
    this(Length!T t) {
         value = t;
    }

    /// 显示细节
    string toString() {
        import std.string;
        // 打印
        return format("%0.2f meters (stored as %s)", value.value / 100, T.stringof);
    }

    auto opBinary(string op, LengthType : Length!T, T)(LengthType rhs) {
        auto helper() {
            auto a = mixin("value.value " ~ op ~ " rhs.value");
            return meters!(typeof(a))(Length!(typeof(a))(a));
        }
        return helper();
    }

    auto opBinary(string op, T)(T rhs) if(isALength!T) {
        return opBinary!op(rhs.value); //转发
    }
}

bool isALength(T)() {
    enum aliasThis = __traits(getAliasThis, T);
    static if(aliasThis.length == 0) {
        return false;
    } else {
        static if(is(typeof(__traits(getMember, T, aliasThis)()) : Length!T, T))//取别名本
            return true;
        else {
            /// 错误类型
            return false;
        }
    }
}

void main() {
    auto l = meters!int(1);
    auto l2 = meters!float(0.12);

    import std.stdio;
    writeln(l + l2); 
}
posted @ 2022-10-15 21:09  zjh6  阅读(23)  评论(0)    收藏  举报  来源