Thread overview
Operator overloading giving encrypted error messages.
Feb 08, 2011
Charles McAnany
Feb 08, 2011
bearophile
Feb 09, 2011
bearophile
February 08, 2011
Hi, all. I'm playing around with a BigRational struct to get more comfortable
with D.
The plan:
Allow binary operators so that a BR (BigRational) is the lhs and one of {BR,
BigInt, int, long} is the rhs.
So BR(5) + 2 compiles just as well as BR(5)+BR(2)
Here's the opBinary code I've worked out:
BigRational opBinary(string op,T)(T arg){
	BigRational y = BigRational(arg);
	static if(op == "+"){
		BigRational temp = this;
	}}} /// and so on, ending with an assert(0) after all the static ifs.

So, unit testing this with
auto br1 = BigRational(25,"2");
writefln("br1+1 = %s",br1+1);
works beautifully.


Now, I'd like to define the ++ to increase this by 1.
So, I write:
BigRational opUnary(string op)(){
	static if(op == "++"){
		this = this+1;
		return this;
//There are other overloads, too.
}}
Now, when I unittest
writefln("br1++ = %s", br1++); //This is line 166.
I get a weird error message:
C:\DProjects\BigRational\src>dmd BigRational.d -unittest
BigRational.d(166): Error: template BigRational.BigRational.opBinary(string op,T
) does not match any function template declaration
BigRational.d(166): Error: template BigRational.BigRational.opBinary(string op,T
) cannot deduce template function from argument types !()()

My issue here is that I have already used the exact same syntax in the first
unit test as my code for the ++ overload has, but here it fails me. (Plus, why
is line 166 having trouble with opBinary? ++ is unary, no?
Any ideas?
Thanks,
Charles.
February 08, 2011
Charles McAnany:

> My issue here is that I have already used the exact same syntax in the first
> unit test as my code for the ++ overload has, but here it fails me. (Plus, why
> is line 166 having trouble with opBinary? ++ is unary, no?
> Any ideas?

In similar situations I suggest you to keep reducing your code until you have a minimal test case. Your code reduced:

struct Foo {
    Foo opUnary(string op:"++")() {
        return this;
    }
    Foo opBinary(string op)(int y) {
        return this;
    }
}
void main() {
    auto f = Foo();
    f++;
}

It sees the post-increment fires the opBinary template too. I think this is a front-end bug, for Bugzilla if confirmed and not already present.

Bye,
bearophile
February 09, 2011
> It sees the post-increment fires the opBinary template too. I think this is a front-end bug, for Bugzilla if confirmed and not already present.

http://d.puremagic.com/issues/show_bug.cgi?id=5551