Jump to page: 1 2
Thread overview
Problem about Tuple.opEquals, const qualifier
Mar 17, 2012
Tongzhou Li
Mar 17, 2012
Ali Çehreli
Mar 18, 2012
Tongzhou Li
Mar 17, 2012
Simen Kjærås
Mar 18, 2012
Tongzhou Li
Mar 18, 2012
Tongzhou Li
Mar 18, 2012
Ali Çehreli
Mar 18, 2012
Tongzhou Li
Mar 18, 2012
Simen Kjærås
Mar 18, 2012
bearophile
March 17, 2012
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:)
March 17, 2012
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
March 17, 2012
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!(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:)

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
March 18, 2012
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.
March 18, 2012
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!(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:)
>
> 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
March 18, 2012
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...
March 18, 2012
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

March 18, 2012
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. :/).
It seems long and ugly...
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?
;)
March 18, 2012
On Sun, 18 Mar 2012 08:34:19 +0100, Tongzhou Li <zhangsongcui@hotmail.com> wrote:

> 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. :/).
> It seems long and ugly...
> 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?
> ;)

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 ~= to!T( element );
}


Works for me with this code:

Tuple!(double, char)[] arr;
arr.push(tuple(10, 'a'));
March 18, 2012
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
« First   ‹ Prev
1 2