Thread overview
opAssign overload question
Apr 25, 2013
gedaiu
Apr 25, 2013
Ali Çehreli
Apr 25, 2013
bearophile
Apr 25, 2013
bearophile
Apr 25, 2013
Ali Çehreli
April 25, 2013
Hi folks,

i have this struct:

import std.stdio, std.string;

struct Value {

	private long intVal;
	private bool boolVal;
        private string type;

        Value opAssign(long val) {
		intVal = val;
		
		if(val == 0) {
			boolVal = false;
		} else {
			boolVal = true;
		}

		type = "LONG";
		
		return this;
	}

    Value opAssign(bool val) {
		if(val) {
			boolVal = true;
			intVal = 1;
		} else {
			boolVal = false;
			intVal = 0;
		}
	
		type = "BOOL";
		
		return this;
	}

	string getType() {
		return type;
	}

}

int main() {
    Value data;
	data = 1;
	
	writeln(data);
	writeln(data.getType());

	assert(data.getType() == "LONG");
	
	return 0;
}

output:
Value(1, true, "BOOL")
BOOL


Can anyone tell me why the compiler call opAssign(bool val) and not opAssign(long val). I am passing an long value not a bool one.

Thanks,
Bogdan
April 25, 2013
On 04/25/2013 11:37 AM, gedaiu wrote:> Hi folks,
>
> i have this struct:

Reduced code:

import std.stdio;

void foo(bool b)
{
    writeln("bool");
}

void foo(long l)
{
    writeln("long");
}

void main()
{
    foo(1);
}

The bool overload gets called...

> Can anyone tell me why the compiler call opAssign(bool val) and not
> opAssign(long val). I am passing an long value not a bool one.

The type of literal 1 is int, not long. So, both functions are matched with implicit conversions. According to "Function Overloading" here:

  http://dlang.org/function.html

The match is later resolved by "If two or more functions have the same match level, then partial ordering is used to try to find the best match. Partial ordering finds the most specialized function."

If bool is considered to be more specialized than long, then the compiler is behaving according to spec. It is very confusing indeed. Especially, considering that an int *variable* would be matched to long:

    auto i = 1;
    foo(i);

Now the long overload gets called!

Ali

April 25, 2013
Ali Çehreli:

> The type of literal 1 is int, not long. So, both functions are matched with implicit conversions. According to "Function Overloading" here:
>
>   http://dlang.org/function.html
>
> The match is later resolved by "If two or more functions have the same match level, then partial ordering is used to try to find the best match. Partial ordering finds the most specialized function."
>
> If bool is considered to be more specialized than long, then the compiler is behaving according to spec. It is very confusing indeed. Especially, considering that an int *variable* would be matched to long:
>
>     auto i = 1;
>     foo(i);
>
> Now the long overload gets called!

This is the code of the OP improved a little:


import std.stdio;

struct Value {
    public enum Type { bool_, long_ }

    private long longVal;
    private bool boolVal;
    private Type type;

    Value opAssign(in long val) pure nothrow {
        longVal = val;
        boolVal = val != 0;

        type = Type.long_;
        return this;
    }

    Value opAssign(in bool val) pure nothrow {
        longVal = val;
        boolVal = val;

        type = Type.bool_;
        return this;
    }

    Type getType() {
        return type;
    }

}

void main() {
    Value data;

    data = 1;
    data.writeln;
    data.getType.writeln;
    assert(data.getType == Value.Type.bool_);

    writeln;

    data = 10;
    data.writeln;
    data.getType.writeln;
    assert(data.getType == Value.Type.long_);
}


Indeed, such implicit casting rules and overload rules are quite arbitrary, and they cause confusion. Functional languages try hard to not have them.

Bye,
bearophile
April 25, 2013
Ali Çehreli:

> If bool is considered to be more specialized than long, then the compiler is behaving according to spec. It is very confusing indeed.

In my code I've shown that 1 matches the bool function and 10 matches the long function. Is this acceptable? It seems a bit ridiculous.

Bye,
bearophile
April 25, 2013
On 04/25/2013 12:48 PM, bearophile wrote:

> Ali Çehreli:
>
>> If bool is considered to be more specialized than long, then the
>> compiler is behaving according to spec. It is very confusing indeed.
>
> In my code I've shown that 1 matches the bool function and 10 matches
> the long function. Is this acceptable? It seems a bit ridiculous.

Now on the main newsgroup:

  http://forum.dlang.org/post/klc5r7$3c4$1@digitalmars.com

Ali