Thread overview
String and opBinary
Jun 01, 2012
Eyyub
Jun 01, 2012
Jonathan M Davis
Jun 01, 2012
Zhenya
Jun 01, 2012
Zhenya
Jun 01, 2012
Dmitry Olshansky
Jun 01, 2012
Eyyub
Jun 01, 2012
Jonathan M Davis
Jun 01, 2012
Eyyub
Jun 01, 2012
bearophile
June 01, 2012
Hi,

I'd like to know why this following code doesn't compile :

string opBinary(string op : "*")(string data, string word)
{
	string temp;
	foreach(letter; word)
	{
		temp ~= data;
	}
	return temp;
}

void main()
{
	string word = "foo";
	string secretword = "_" * word; //Error: '"_"' is not of arithmetic type                            it is a string
        //Error: 'word' is not of arithmetic type, it is a string
	string secretword = "_".opBinary!"*"(word); // compile
	writeln(secretword); // output : ___
}

Even more weird, with just another op specialisation but the same function's body :
string opBinary(string op : "+")(string data, string word)
{
	string temp;
	foreach(letter; word)
	{
		temp ~= data;
	}
	return temp;
}

void main()
{
	string word = "foo";
	string secretword = "_" + word; // Error: Array operation "_" - word not implemented // why the error message is not the same with different op ?
	string secretword = "_".opBinary!"+"(word); // this works fine
}

Thanks,

(sorry for my bad english)
June 01, 2012
On Friday, June 01, 2012 19:51:35 Eyyub wrote:
> Hi,
> 
> I'd like to know why this following code doesn't compile :
> 
> string opBinary(string op : "*")(string data, string word)
> {
> string temp;
> foreach(letter; word)
> {
> temp ~= data;
> }
> return temp;
> }
> 
> void main()
> {
> string word = "foo";
> string secretword = "_" * word; //Error: '"_"' is not of
> arithmetic type it is a string
> //Error: 'word' is not of arithmetic type, it is a string
> string secretword = "_".opBinary!"*"(word); // compile
> writeln(secretword); // output : ___
> }
> 
> Even more weird, with just another op specialisation but the same
> function's body :
> string opBinary(string op : "+")(string data, string word)
> {
> string temp;
> foreach(letter; word)
> {
> temp ~= data;
> }
> return temp;
> }
> 
> void main()
> {
> string word = "foo";
> string secretword = "_" + word; // Error: Array operation "_" -
> word not implemented // why the error message is not the same
> with different op ?
> string secretword = "_".opBinary!"+"(word); // this works fine
> }
> 
> Thanks,
> 
> (sorry for my bad english)

I don't believe that it's legal to declare overloaded operators for built-in types. So, it's not legal to do what you're trying to do. You can call the function directly, because it's a valid function, but it isn't used to overload any operators.

As for why you're getting a complaint about subtraction in the second example, I don't know. Running the current, development version from github I get a +, so it may be a bug in whatever version of the compiler that you're using that has since been fixed.

- Jonathan M Davis
June 01, 2012
On Friday, 1 June 2012 at 17:51:36 UTC, Eyyub wrote:
> Hi,
>
> I'd like to know why this following code doesn't compile :
>
> string opBinary(string op : "*")(string data, string word)
> {
> 	string temp;
> 	foreach(letter; word)
> 	{
> 		temp ~= data;
> 	}
> 	return temp;
> }
>
> void main()
> {
> 	string word = "foo";
> 	string secretword = "_" * word; //Error: '"_"' is not of arithmetic type                            it is a string
>         //Error: 'word' is not of arithmetic type, it is a string
> 	string secretword = "_".opBinary!"*"(word); // compile
> 	writeln(secretword); // output : ___
> }
>
> Even more weird, with just another op specialisation but the same function's body :
> string opBinary(string op : "+")(string data, string word)
> {
> 	string temp;
> 	foreach(letter; word)
> 	{
> 		temp ~= data;
> 	}
> 	return temp;
> }
>
> void main()
> {
> 	string word = "foo";
> 	string secretword = "_" + word; // Error: Array operation "_" - word not implemented // why the error message is not the same with different op ?
> 	string secretword = "_".opBinary!"+"(word); // this works fine
> }
>
> Thanks,
>
> (sorry for my bad english)
Hi,Eyyub
//Operator overloading is accomplished by rewriting operators whose operands //are class or struct objects into calls to specially named member functions
I'm not sure,but problem may be that opBinary should be member function
June 01, 2012
Eyyub:

> I'd like to know why this following code doesn't compile :
>
> string opBinary(string op : "*")(string data, string word)
> {
> 	string temp;
> 	foreach(letter; word)
> 	{
> 		temp ~= data;
> 	}
> 	return temp;
> }

In D to work an overloaded operator like that needs to be a
class/struct method.

Bye,
bearophile
June 01, 2012
This code work

import std.stdio;

struct String
{
	string data;
	alias data this;
	this(string s)
	{
		data = s;
	}
	String opBinary(string op : "*")(string word)
	{
		string temp;
		foreach(letter; word)
		{
			temp ~= data;
		}
		return String(temp);
	}
};

string opBinary(string op : "*")(string data, string word)
{
	string temp;
	foreach(letter; word)
	{
		temp ~= data;
	}
	return temp;
}

void main()
{
	String word = "foo";
	String secretword = String("_") * word;
 	//string secretword = "_".opBinary!"*"(word); // compile
	writeln(secretword); // output : ___
}


June 01, 2012
On 01.06.2012 23:37, Zhenya wrote:
> This code work
>
> import std.stdio;
>
> struct String
> {
> string data;
> alias data this;
> this(string s)
> {
> data = s;
> }
> String opBinary(string op : "*")(string word)
> {
> string temp;
> foreach(letter; word)
> {
> temp ~= data;
> }
> return String(temp);
> }
> };
>
> string opBinary(string op : "*")(string data, string word)
> {
> string temp;
> foreach(letter; word)
> {
> temp ~= data;
> }
> return temp;
> }
>
> void main()
> {
> String word = "foo";
> String secretword = String("_") * word;

Define proper opBinaryRight and this will work too:
String secretword = "_" * word;

> //string secretword = "_".opBinary!"*"(word); // compile
> writeln(secretword); // output : ___
> }
>
>


-- 
Dmitry Olshansky
June 01, 2012
On Friday, 1 June 2012 at 19:37:38 UTC, Zhenya wrote:
> This code work
>
> import std.stdio;
>
> struct String
> {
> 	string data;
> 	alias data this;
> 	this(string s)
> 	{
> 		data = s;
> 	}
> 	String opBinary(string op : "*")(string word)
> 	{
> 		string temp;
> 		foreach(letter; word)
> 		{
> 			temp ~= data;
> 		}
> 		return String(temp);
> 	}
> };
>
> string opBinary(string op : "*")(string data, string word)
> {
> 	string temp;
> 	foreach(letter; word)
> 	{
> 		temp ~= data;
> 	}
> 	return temp;
> }
>
> void main()
> {
> 	String word = "foo";
> 	String secretword = String("_") * word;
>  	//string secretword = "_".opBinary!"*"(word); // compile
> 	writeln(secretword); // output : ___
> }

Hi Zhenya, thanks for your reply !

I considered using this tip but that doesn't look nice compared to the C++ way does it. :/

Why doesn't D allow a way to write operator overloading at scope-module level like in C++ ?(in this case)

(Thanks for your tip Dmitry)
June 01, 2012
On Friday, June 01, 2012 22:18:50 Eyyub wrote:
> Why doesn't D allow a way to write operator overloading at scope-module level like in C++ ?(in this case)

Why would you need to? It only works when defining them for user-defined types anyway. So, having them be member functions makes perfect sense. And opBinaryRight solves the problem of needing the overload where the other type is on the left rather than the one that you're defining the overloaded operator for, which is the typical reason to define an overloaded operator as a friend function rather than a member function in C++.

- Jonathan M Davis
June 01, 2012
On Friday, 1 June 2012 at 21:26:55 UTC, Jonathan M Davis wrote:
> On Friday, June 01, 2012 22:18:50 Eyyub wrote:
>> Why doesn't D allow a way to write operator overloading at
>> scope-module level like in C++ ?(in this case)
>
> Why would you need to? It only works when defining them for user-defined types
> anyway. So, having them be member functions makes perfect sense. And
> opBinaryRight solves the problem of needing the overload where the other type
> is on the left rather than the one that you're defining the overloaded operator
> for, which is the typical reason to define an overloaded operator as a friend
> function rather than a member function in C++.
>
> - Jonathan M Davis

Hi,

I asked this question just for know if there are a reason about
this choice.

Anyway, want to multiply a string by a string is a non-sense. :P

Thanks,