November 29, 2014 Re: Can't understand templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta | You miss another definition which introduces a conflict:
T getResponse(T)(string question)
{...}
On Saturday, 29 November 2014 at 17:20:42 UTC, Meta wrote:
> On Saturday, 29 November 2014 at 11:07:34 UTC, Sly wrote:
>> On Saturday, 29 November 2014 at 09:11:51 UTC, Ali Çehreli wrote:
>>
>>> Point!T getResponse(P : Point!T, T)(string question)
>>> {
>>> // ...
>>> }
>>>
>>
>> This doesn't work because now this definition has 2 parameters P
>> and T. I have to specify both like this: auto pt =
>> getResponse!(Point!int, int)("point"); which of course defeats
>> the purpose. Otherwise I have ambiguity error:
>
> Not true, T is inferred based on the the type Point has been instantiated with, letting you emit the second template argument. The following code works:
>
> struct Point(T)
> {
> T x;
> T y;
> }
>
> P getResponse(P: Point!T, T)(string message)
> {
> return P(T.init, T.init);
> }
>
> void main()
> {
> import std.stdio;
>
> //T is inferred to be int automatically
> writeln(getResponse!(Point!int)("test"));
> }
| |||
November 29, 2014 Re: Can't understand templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sly | On Saturday, 29 November 2014 at 18:19:40 UTC, Sly wrote: > You miss another definition which introduces a conflict: > T getResponse(T)(string question) > {...} In that case, you're better off with a pair of declarations: struct Point(T) { T x; T y; } T getResponse(T)(string message) if (!is(T == Point!U, U)) { return T.init; } Point!T getResponse(T)(string message) if (is(T == Point!U, U)) { return Point!T(T.init, T.init); } void main() { auto t = getResponse!int("test"); auto p = getResponse!(Point!int)("test"); } | |||
November 29, 2014 Re: Can't understand templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta | This is clearly an incorrect way because it requires editing the
original definition every time a new class is introduced.
On Saturday, 29 November 2014 at 19:10:34 UTC, Meta wrote:
> On Saturday, 29 November 2014 at 18:19:40 UTC, Sly wrote:
>> You miss another definition which introduces a conflict:
>> T getResponse(T)(string question)
>> {...}
>
> In that case, you're better off with a pair of declarations:
>
> struct Point(T)
> {
> T x;
> T y;
> }
>
> T getResponse(T)(string message)
> if (!is(T == Point!U, U))
> {
> return T.init;
> }
>
> Point!T getResponse(T)(string message)
> if (is(T == Point!U, U))
> {
> return Point!T(T.init, T.init);
> }
>
> void main()
> {
> auto t = getResponse!int("test");
> auto p = getResponse!(Point!int)("test");
> }
| |||
November 29, 2014 Re: Can't understand templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sly | On 11/29/2014 10:19 AM, Sly wrote:
> You miss another definition which introduces a conflict:
> T getResponse(T)(string question)
> {...}
The following works with dmd git head:
import std.stdio;
T getResponse(T)(string question)
{
writef("%s (%s): ", question, T.stringof);
T response;
readf(" %s", &response);
return response;
}
class Pair(A, B) {
A a;
B b;
this(A a, B b) {this.a = a; this.b = b;}
}
Pair!(A, B) getResponse(P : Pair!(A, B), A, B)(string question)
{
writeln(question);
auto a = getResponse!A(" a");
auto b = getResponse!B(" b");
return new Pair!(A, B)(a, b);
}
struct Point(T)
{
T x;
T y;
}
Point!T getResponse(P : Point!T, T)(string question)
{
writefln("%s (Point!%s)", question, T.stringof);
auto x = getResponse!T(" x");
auto y = getResponse!T(" y");
return Point!T(x, y);
}
void main()
{
auto number = getResponse!int("number?");
writeln(number);
auto pair = getResponse!(Pair!(int, long))("pair?");
writeln(pair);
auto point = getResponse!(Point!int)("point?");
writeln(point);
}
Ali
| |||
November 29, 2014 Re: Can't understand templates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | OK. I'm using gdc 4.8.2 and this doesn't compile, so it's
probably an old version. Checked on ideone and it works with
dmd-2.042.
Thanks a lot for your help!
On Saturday, 29 November 2014 at 20:16:24 UTC, Ali Çehreli wrote:
> On 11/29/2014 10:19 AM, Sly wrote:
>
> > You miss another definition which introduces a conflict:
> > T getResponse(T)(string question)
> > {...}
>
> The following works with dmd git head:
>
> import std.stdio;
>
> T getResponse(T)(string question)
> {
> writef("%s (%s): ", question, T.stringof);
>
> T response;
> readf(" %s", &response);
>
> return response;
> }
>
> class Pair(A, B) {
> A a;
> B b;
> this(A a, B b) {this.a = a; this.b = b;}
> }
>
> Pair!(A, B) getResponse(P : Pair!(A, B), A, B)(string question)
> {
> writeln(question);
> auto a = getResponse!A(" a");
> auto b = getResponse!B(" b");
> return new Pair!(A, B)(a, b);
> }
>
> struct Point(T)
> {
> T x;
> T y;
> }
>
> Point!T getResponse(P : Point!T, T)(string question)
> {
> writefln("%s (Point!%s)", question, T.stringof);
>
> auto x = getResponse!T(" x");
> auto y = getResponse!T(" y");
>
> return Point!T(x, y);
> }
>
> void main()
> {
> auto number = getResponse!int("number?");
> writeln(number);
>
> auto pair = getResponse!(Pair!(int, long))("pair?");
> writeln(pair);
>
> auto point = getResponse!(Point!int)("point?");
> writeln(point);
> }
>
> Ali
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply