www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problem about Tuple.opEquals, const qualifier

reply "Tongzhou Li" <zhangsongcui hotmail.com> writes:
I'm learning D, and trying to convert My C++ code into D:
http://pastebin.com/eCz9DdZ3
I wrote: auto stack = SList!(Tuple!(double, char))();
But I got an error
Error: function 
std.typecons.Tuple!(double,char).Tuple.opEquals!(const(Tuple!(dou
le,char))).opEquals 
(const(Tuple!(double,char)) rhs) is not callable using argument 
types (const(Tuple!(double,char))) const
Does the function Tuple.opEquals miss a const qualifier?
Sorry for my bad English:)
Mar 17 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/17/2012 09:27 AM, Tongzhou Li wrote:
 I'm learning D, and trying to convert My C++ code into D:
 http://pastebin.com/eCz9DdZ3
 I wrote: auto stack = SList!(Tuple!(double, char))();
 But I got an error
 Error: function
 std.typecons.Tuple!(double,char).Tuple.opEquals!(const(Tuple!(double,char))).opEquals
 (const(Tuple!(double,char)) rhs) is not callable using argument types
 (const(Tuple!(double,char))) const
 Does the function Tuple.opEquals miss a const qualifier?
 Sorry for my bad English:)

There are still many const-correctness issues with Phobos. You hit this bug: http://d.puremagic.com/issues/show_bug.cgi?id=5783 Ali
Mar 17 2012
prev sibling next sibling parent reply =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
On Sat, 17 Mar 2012 17:27:21 +0100, Tongzhou Li <zhangsongcui hotmail.com>  
wrote:

 I'm learning D, and trying to convert My C++ code into D:
 http://pastebin.com/eCz9DdZ3
 I wrote: auto stack = SList!(Tuple!(double, char))();
 But I got an error
 Error: function  
 std.typecons.Tuple!(double,char).Tuple.opEquals!(const(Tuple!(dou
le,char))).opEquals  
 (const(Tuple!(double,char)) rhs) is not callable using argument types  
 (const(Tuple!(double,char))) const
 Does the function Tuple.opEquals miss a const qualifier?
 Sorry for my bad English:)

As others have pointed out, there are const-correctness bugs. As for a workaround, have you considered using a simple array instead of a linked list? Arrays in D, especially when combined with std.array, make for easy-to-use (though perhaps not particularly efficient) stacks: int[] stack; stack ~= 3; // Push stack = stack[0..$-1]; // Pop stack.popBack(); // Pop with std.array
Mar 17 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/17/2012 09:02 PM, Tongzhou Li wrote:
 On Saturday, 17 March 2012 at 23:05:30 UTC, Simen Kjærås wrote:
 As for a workaround, have you considered using a simple array instead
 of a linked list?
 Arrays in D, especially when combined with std.array, make for
 easy-to-use (though
 perhaps not particularly efficient) stacks:

 int[] stack;

 stack ~= 3; // Push
 stack = stack[0..$-1]; // Pop
 stack.popBack(); // Pop with std.array

Another problem. I wrote: Tuple!(double, char)[] stack; stack ~= tuple(10, '+'); It won't compile: Error: cannot append type Tuple!(int,char) to type Tuple!(double,char)[]

Every template instantiation of a set of template parameters becomes a distinct type than any other set of template parameters. In other words, Tuple!(double, char) and Tuple!(int, char) are distinct types. For all the compiler knows, Tuple is a user type and only the user should define whether they are compatible. Tuple does not define opCast() to covert from Tuple!(int,char) to Tuple!(double,char). I guess it could have been defined. (?) A solution is to explicitly perform the conversion: import std.conv; // ... stack ~= to!(Tuple!(double, char))(tuple(10, '+')); (An alias would make that easier to read. :/).
 I also tried:
 Tuple!(double, "Num", char, "Oper")[] stack;
 stack ~= tuple(10.0, '+');
 I also got an error:
 Error: cannot append type Tuple!(double,char) to type
 Tuple!(double,"Num",char,"Oper")[]

That's the same reason as above.
 But I tried:
 Tuple!(double, "Num", char, "Oper") t;
 t = tuple(10, 'a');
 It does compile.
 I don't understand why...

That's different because this time there is no slice involved. The assignment is done on t itself. Tuple defines opAssign() that effectively performs the following operations (calling the right-hand side object 'temp'): t[0] = temp[0]; t[1] = temp[1]; And that succeeds because int can implicitly be converted to double. Ali
Mar 17 2012
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Tongzhou Li:

 Another problem. I wrote:
      Tuple!(double, char)[] stack;
      stack ~= tuple(10, '+');
 It won't compile:

I have already shown here how to solve that problem: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=33749 import std.typecons; void main() { alias Tuple!(double, char) Pair2; Pair2[] stack; stack ~= Pair2(10, '+'); } Bye, bearophile
Mar 18 2012
prev sibling next sibling parent "Tongzhou Li" <zhangsongcui hotmail.com> writes:
On Saturday, 17 March 2012 at 19:49:24 UTC, Ali Çehreli wrote:
 On 03/17/2012 09:27 AM, Tongzhou Li wrote:
 I'm learning D, and trying to convert My C++ code into D:
 http://pastebin.com/eCz9DdZ3
 I wrote: auto stack = SList!(Tuple!(double, char))();
 But I got an error
 Error: function
 std.typecons.Tuple!(double,char).Tuple.opEquals!(const(Tuple!(double,char))).opEquals
 (const(Tuple!(double,char)) rhs) is not callable using 
 argument types
 (const(Tuple!(double,char))) const
 Does the function Tuple.opEquals miss a const qualifier?
 Sorry for my bad English:)

There are still many const-correctness issues with Phobos. You hit this bug: http://d.puremagic.com/issues/show_bug.cgi?id=5783 Ali

OK. I hope it can be fixed soon.
Mar 17 2012
prev sibling next sibling parent "Tongzhou Li" <zhangsongcui hotmail.com> writes:
On Saturday, 17 March 2012 at 23:05:30 UTC, Simen Kjærås wrote:
 On Sat, 17 Mar 2012 17:27:21 +0100, Tongzhou Li 
 <zhangsongcui hotmail.com> wrote:

 I'm learning D, and trying to convert My C++ code into D:
 http://pastebin.com/eCz9DdZ3
 I wrote: auto stack = SList!(Tuple!(double, char))();
 But I got an error
 Error: function 
 std.typecons.Tuple!(double,char).Tuple.opEquals!(const(Tuple!(dou
le,char))).opEquals 
 (const(Tuple!(double,char)) rhs) is not callable using 
 argument types (const(Tuple!(double,char))) const
 Does the function Tuple.opEquals miss a const qualifier?
 Sorry for my bad English:)

As others have pointed out, there are const-correctness bugs. As for a workaround, have you considered using a simple array instead of a linked list? Arrays in D, especially when combined with std.array, make for easy-to-use (though perhaps not particularly efficient) stacks: int[] stack; stack ~= 3; // Push stack = stack[0..$-1]; // Pop stack.popBack(); // Pop with std.array

Seems good! I'll have a try. Thanks
Mar 17 2012
prev sibling next sibling parent "Tongzhou Li" <zhangsongcui hotmail.com> writes:
On Saturday, 17 March 2012 at 23:05:30 UTC, Simen Kjærås wrote:
 As for a workaround, have you considered using a simple array 
 instead of a linked list?
 Arrays in D, especially when combined with std.array, make for 
 easy-to-use (though
 perhaps not particularly efficient) stacks:

 int[] stack;

 stack ~= 3; // Push
 stack = stack[0..$-1]; // Pop
 stack.popBack(); // Pop with std.array

Another problem. I wrote: Tuple!(double, char)[] stack; stack ~= tuple(10, '+'); It won't compile: Error: cannot append type Tuple!(int,char) to type Tuple!(double,char)[] I also tried: Tuple!(double, "Num", char, "Oper")[] stack; stack ~= tuple(10.0, '+'); I also got an error: Error: cannot append type Tuple!(double,char) to type Tuple!(double,"Num",char,"Oper")[] But I tried: Tuple!(double, "Num", char, "Oper") t; t = tuple(10, 'a'); It does compile. I don't understand why...
Mar 17 2012
prev sibling next sibling parent "Tongzhou Li" <zhangsongcui hotmail.com> writes:
On Sunday, 18 March 2012 at 06:15:16 UTC, Ali Çehreli wrote:
 Every template instantiation of a set of template parameters 
 becomes a distinct type than any other set of template 
 parameters.

 In other words, Tuple!(double, char) and Tuple!(int, char) are 
 distinct types. For all the compiler knows, Tuple is a user 
 type and only the user should define whether they are 
 compatible. Tuple does not define opCast() to covert from 
 Tuple!(int,char) to Tuple!(double,char). I guess it could have 
 been defined. (?)

 A solution is to explicitly perform the conversion:

 import std.conv;
 // ...
     stack ~= to!(Tuple!(double, char))(tuple(10, '+'));

 (An alias would make that easier to read. :/).

I also write: Tuple!(uint, double delegate(double, double))[char] Operators; Operators['+'] = tuple(1u, (x, y) => x + y); It doesn't work. I have to write: Operators['+'] = tuple(1u, cast(double delegate(double, double))(x, y) => x + y); Much longer :/ Someone tell me that this is called SFINAE problem in C++ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html I tried this C++ code: stack<pair<double, char> > s; s.push(make_pair(10, '+')); It compiles fine with g++. Any chance to see this being solved in D? ;)
Mar 18 2012
prev sibling next sibling parent =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
On Sun, 18 Mar 2012 08:34:19 +0100, Tongzhou Li <zhangsongcui hotmail.co=
m>  =

wrote:

 On Sunday, 18 March 2012 at 06:15:16 UTC, Ali =C3=87ehreli wrote:
 Every template instantiation of a set of template parameters becomes =


 distinct type than any other set of template parameters.

 In other words, Tuple!(double, char) and Tuple!(int, char) are distin=


 types. For all the compiler knows, Tuple is a user type and only the =


 user should define whether they are compatible. Tuple does not define=


 opCast() to covert from Tuple!(int,char) to Tuple!(double,char). I  =


 guess it could have been defined. (?)

 A solution is to explicitly perform the conversion:

 import std.conv;
 // ...
     stack ~=3D to!(Tuple!(double, char))(tuple(10, '+'));

 (An alias would make that easier to read. :/).

I also write: Tuple!(uint, double delegate(double, double))[char] Operators; Operators['+'] =3D tuple(1u, (x, y) =3D> x + y); It doesn't work. I have to write: Operators['+'] =3D tuple(1u, cast(double delegate(double, double)=

 y) =3D> x + y);
 Much longer :/

 Someone tell me that this is called SFINAE problem in C++
 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html
 I tried this C++ code:
      stack<pair<double, char> > s;
      s.push(make_pair(10, '+'));
 It compiles fine with g++.
 Any chance to see this being solved in D?
 ;)

Try this one for size: import std.traits : isImplicitlyConvertible, isSomeChar, isAssignable; import std.conv : to; void push( T, U )( ref T[] arr, U element ) if = (isImplicitlyConvertible!(U, T) || (isSomeChar!T && isSomeChar!U) || isAssignable!(T, U) ) { arr ~=3D to!T( element ); } Works for me with this code: Tuple!(double, char)[] arr; arr.push(tuple(10, 'a'));
Mar 18 2012
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 17 Mar 2012 19:05:24 -0400, Simen Kj=C3=A6r=C3=A5s <simen.kjaras=
 gmail.com>  =

wrote:

 As for a workaround, have you considered using a simple array instead =

 a linked list?
 Arrays in D, especially when combined with std.array, make for  =

 easy-to-use (though
 perhaps not particularly efficient) stacks:

 int[] stack;

 stack ~=3D 3; // Push
 stack =3D stack[0..$-1]; // Pop
 stack.popBack(); // Pop with std.array

stack.assumeSafeAppend(); You need that line, or the next append will reallocate the entire array.= -Steve
Mar 19 2012