View mode: basic / threaded / horizontal-split · Log in · Help
June 01, 2012
String and opBinary
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
Re: String and opBinary
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
Re: String and opBinary
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
Re: String and opBinary
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
Re: String and opBinary
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
Re: String and opBinary
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
Re: String and opBinary
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
Re: String and opBinary
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
Re: String and opBinary
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,
Top | Discussion index | About this forum | D home