On 04/08/2019 05:59 AM, Ron Tarrant wrote:
On Monday, 8 April 2019 at 12:40:10 UTC, Adam D. Ruppe wrote:

You don't need template keyword for the majority of cases because the compiler lets you do shortcuts.
Thanks, Adam. Good to know.


(maybe I am looking at the wrong part of the book, it is hard to find the right section/page number online).

My bad. The edition I'm working from was released 2018-10-17 and can be found here:

http://ddili.org/ders/d.en/Programming_in_D.pdf

The page number in online PDF viewer is 421 and the example is about 1/3 of the way down the page.


That template specialization works along with the general definition of the same template. So, you must have the following function template as well:

T getResponse(T)(string question) {
    writef("%s (%s): ", question, T.stringof);

    T response;
    readf(" %s", &response);

    return response;
}

As Steve said, when you replace all Ts in there e.g. with int, you get what the compiler would generate for T being int. However, the readf above cannot work with e.g. Point!double because readf does not know what Point!double is. For that reason, we may use a specialization for Point!T:

Point!T getResponse(T : Point!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));

} // getResponse() Point!T

(It may be made to work with Adam's (T : Point!R, R) syntax but I failed just now.)

Now you have a specialization that works with any Point!T. T can be double, int, etc. However, you must call getResponse with that special Point. I'm using an alias for code reduction:

  alias MapLocation = Point!double;
auto wayPoint1 = getResponse!MapLocation("Where is the first map location?"); auto wayPoint2 = getResponse!MapLocation("Where is the second map location?");

Your code did not work because Point is not a type but a type template. (On the other hand, Point!double is a type). The whole program:

import std.stdio;
import std.math;
import std.string;

struct Point(T)
{
    T x;
    T y;

    T distanceTo(Point that) const
    {
        immutable real xDistance = x - that.x;
        immutable real yDistance = y - that.y;

immutable distance = sqrt((xDistance * xDistance) + (yDistance * yDistance));

        return(cast(T)distance);

    } // distanceTo()

} // struct Point

T getResponse(T)(string question) {
    writef("%s (%s): ", question, T.stringof);

    T response;
    readf(" %s", &response);

    return response;
}

Point!T getResponse(T : Point!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));

} // getResponse() Point!T


void main()
{
  alias MapLocation = Point!double;
auto wayPoint1 = getResponse!MapLocation("Where is the first map location?"); auto wayPoint2 = getResponse!MapLocation("Where is the second map location?");

    writeln("Distance: ", wayPoint1.distanceTo(wayPoint2));

} // main()

Ali

Reply via email to