Functions have to know their type. It would be pretty hard to generate code for them otherwise, and the linker certainly couldn't deal with them. That being said, like C++, D has templates, so you can declare function templates so that the function itself is generated and compiled when code using it is compiled. So, if you want a function that takes two arguments of the same type but will work with various types, then you'll want to use a function template. e.g.
void foo(T)(T a, T b)
{
...
}
Or if multiple types were needed, you could do something like
void foo(T, U)(T a, U b)
{
...
}
In either case, when code then calls foo, the types of the parameters will be inferred by the compiler from the types of the actual arguments. Calling the same function template with different argument types will result in additional functions being generated by the compiler. The relevant part of the official docs is here:
http://dlang.org/spec/template.html#function-templates
But this chapter from an online book would probably be more informative:
http://ddili.org/ders/d.en/templates.html
I'd suggest that you consider reading the whole book (or at least looking it over) if you want something that explains a lot of the basics of D.