Search code examples
dtemplate-specialization

Understanding templating in D


I am teaching myself 'D' and I had, what may appear basic to some, a question regarding templating. For example, the article I am currently reading (please see the bottom of this post) contains the following code:

int foo(int x)
{
    return x;
}

string foo(string x)
{
    return x;
}

void main()
{
    assert(foo(12345) == 12345);
    assert(foo("hello") == "hello");
}

Obviously, this specific snippet is less than elegant and a template would eliminate the repetition:

foo(T)(T x)
{
    return x;
}

void main()
{
    assert(foo!(int)(12345) == 12345);
    assert(foo!(string)("hello") == "hello");
}

The second example is rather basic since we are merely returning the value passed. My confusion arises by the fact that the function, however templated, still appears to be constrained to one type of value since I cannot easily envision a string and an integer value having a great deal in common. Therefore, is a programmer expected to check for the type of variable passed and then write code to handle cases of string or integer separately? Is creating a large function body truly more efficient? I realize my unfamiliarity with templating is obvious. Hence my question :)

http://nomad.so/2013/07/templates-in-d-explained/


Solution

  • The literal definition of "template" is "something that serves as a model for others to copy" and that is what the compiler does. For each type (string and int in your case) it copies the template function and creates a specialized function during compilation.

    There is no need for the template at run time, so that can be thrown away after compilation. In the compiled binary there are two functions foo!(int) and foo!(string).

    Is a programmer expected to check for the type of variable passed and then write code to handle cases of string or integer separately?

    That depends. Sometimes you want to do that. For example, to optimize for performance. Sometimes you don't need to do that and write a generic functions.

    Is creating a large function body truly more efficient?

    Sometimes. If not, then don't do it. For example, you can write one generic find function, which works on arrays, linked lists, and similar stuff.