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