www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template constraints and opAdd

reply "John" <dont email.me> writes:
I'm getting conflicting templates in this struct and I'm not sure 
how. I specifically excluded the second definition of opAdd from 
using type T in place of O but the compiler still tells me I'm 
getting template conflicts.

Compiler error using Mass!(double,string):

Error: template mass.Mass!(double,string).Mass.opAdd(O) if 
((typeof(O)) != (typeof(T))) conflicts with function 
mass.Mass!(double,string).Mass.opAdd at src\mass.d(38)


I have a struct:

struct Mass(T, S) {
	...
	
	Mass!(T,S) opAdd(Mass!(T,S) other) {
		return op!"+"(other);
	}
	
	Mass!(O,S) opAdd(O)(Mass!(O,S) other) if (typeof(O) != 
typeof(T)) {
		return op!"+"(other);
	}
...
}

And I'm trying to do something like:

	Mass!(double,string) first = ...
	Mass!(double,string) second = ...
	
	auto result = first + second;

I'm trying to add a Mass!(double,string) + Mass!(double,string), 
which should mean the second template gets ignored since T=double 
and O=double.

What am I missing?
Jul 01 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
John:

 	Mass!(T,S) opAdd(Mass!(T,S) other) {
If you are using D2 then don't use opAdd, use opBinary: http://dlang.org/operatoroverloading.html#Binary Bye, bearophile
Jul 01 2013
next sibling parent reply "John" <dont email.me> writes:
On Tuesday, 2 July 2013 at 00:01:48 UTC, bearophile wrote:
 John:

 	Mass!(T,S) opAdd(Mass!(T,S) other) {
If you are using D2 then don't use opAdd, use opBinary: http://dlang.org/operatoroverloading.html#Binary Bye, bearophile
Thanks, I switched over to using the new function and after fiddling with the functions I came up with a pair that seem to work. Mass!(T,S) opBinary(alias operator)(Mass!(T,S) other) { Mass!(T,S) opBinary(alias operator, O)(Mass!(O,S) other) if (!is(O == T)) {
Jul 01 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
John:

 Mass!(T,S) opBinary(alias operator)(Mass!(T,S) other) {
 Mass!(T,S) opBinary(alias operator, O)(Mass!(O,S) other) if 
 (!is(O == T)) {
Isn't operator better as string? ---------------------- anonymous:
 You can't overload non-templates with templates,
I think it was recently fixed in Git. Bye, bearophile
Jul 01 2013
parent reply "anonymous" <anonymous example.com> writes:
On Tuesday, 2 July 2013 at 01:24:18 UTC, bearophile wrote:
 anonymous:

 You can't overload non-templates with templates,
I think it was recently fixed in Git.
It's still buggy then, since adding the empty parentheses makes the error go away.
Jul 01 2013
parent "anonymous" <anonymous example.com> writes:
On Tuesday, 2 July 2013 at 01:39:22 UTC, anonymous wrote:
 On Tuesday, 2 July 2013 at 01:24:18 UTC, bearophile wrote:
 anonymous:

 You can't overload non-templates with templates,
I think it was recently fixed in Git.
It's still buggy then, since adding the empty parentheses makes the error go away.
... or maybe my checkout wasn't up to date ;)
Jul 01 2013
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
 John:

 	Mass!(T,S) opAdd(Mass!(T,S) other) {
If you are using D2 then don't use opAdd, use opBinary: http://dlang.org/operatoroverloading.html#Binary
Time ago I added an enhancement request for a warning (that later is meant to become a deprecation) that helps avoid your problem: http://d.puremagic.com/issues/show_bug.cgi?id=10320 Bye, bearophile
Jul 02 2013
prev sibling parent "anonymous" <anonymous example.com> writes:
On Monday, 1 July 2013 at 23:36:27 UTC, John wrote:
 struct Mass(T, S) {
 	...
 	
 	Mass!(T,S) opAdd(Mass!(T,S) other) {
You can't overload non-templates with templates, yet. It's supposed to work, but not implemented. The workaround is simple enough: Mass!(T,S) opAdd()(Mass!(T,S) other) { // note the () after opAdd
 		return op!"+"(other);
 	}
 	
 	Mass!(O,S) opAdd(O)(Mass!(O,S) other) if (typeof(O) != 
 typeof(T)) {
That constraint should be: if (!is(O == T))
 		return op!"+"(other);
 	}
 ...
 }
Jul 01 2013