It seems particularly tricky to define a template in a module and then instantiate it or specialize it somewhere else.
It seems particularly tricky to define a template in a module and then instantiate it or specialize it somewhere else.
D also has an `alias` feature, where you can do things like:
alias Q = abc.T;
where from then on, `abc.T` can be referred to simply as `Q`. This also eliminates a large chunk of purpose behind the preprocessor.C++ has adapted the ‘using’ keyword now to seem fairly similar to alias, but can’t completely subsume macros unfortunately.
It replaces the preprocesser:
#define Q abc.T
with hygiene. Once you get used to it, it has all kinds of nice uses.For normal functions or classes, we have forward declarations. Something similar needs to exist for templates.
D does not require names in global scope to be declared lexically before they are used. C++ only does this for class/struct scopes. For example:
int bar() { foo(); }
int foo() { bar(); }
compiles and runs (and runs, and runs, and runs!!!).But how do you handle a template substitution failure? In C++:
template<typename T>
auto bar(T x, T y)
{ return x + y;}
The compiler has no idea whether bar(1, 2); will compile unless it parses the full definition. I don't understand how the compiler can avoid parsing the full definition.The expensive bit in my experience isn't parsing the declaration, it's parsing the definition. Typically redundantly over thousands of source files for identical types.
This seems incredibly wasteful, but of course still marginal better than just #including code which is the alternative.