On 4/27/20 1:19 PM, jmh530 wrote:
When using a template with multiple functions within it, is it possible
to access the underlying functions directly? Not sure I am missing
anything, but what works when the functions are named differently from
the headline template doesn't work when the functions are named the same.
import std.stdio: writeln;
import std.traits: isFunction;
template foo(T) {
void foo(U)(U x) {
writeln("here0");
}
void foo(U, V)(U x, V y) {
writeln("there0");
}
}
template bar(T) {
void baz(U)(U x) {
writeln("here1");
}
void baz(U, V)(U x, V y) {
writeln("there1");
}
}
void foobar(T)(T x) {}
void main() {
foo!int.foo!(float, double)(1f, 2.0); //Error: template foo(U)(U x)
does not have property foo
foo!int aliases to the template foo's inside, so you are already in there.
In reality, you should want to use foo!int!(float, double), but that
does not parse.
You can do:
alias x = foo!int;
x!(float, double)(...)
or you can just use IFTI:
foo!int(1f, 2.0);
writeln(isFunction!(foo!int)); //prints false, as expected b/c not
smart enough to look through
No, because the template hasn't been instantiated. Note that
isFunction!(foobar) prints false also.
writeln(isFunction!(foo!int.foo!float)); //Error: template
identifier foo is not a member of template onlineapp.foo!int.foo(U)(U x)
An eponymous template is equivalent to the members that have the same
name. There is no way to access the template namespace (this was changed
some time ago).
with x definition above:
writeln(isFunction!(x!float)); // true
writeln(isFunction!(foo!int.foo!(float, double))); //ditto
bar!int.baz!(float, double)(1f, 2.0); //prints there1
writeln(isFunction!(bar!int.baz!(float, double))); //prints true
writeln(isFunction!(foobar!int)); //prints true
}
Generally it's just fine to do foo(T, U, V) and dispense with the double
templates, as IFTI will take care of the other two.
The main reason to have nested templates is when you need to bind the
explicit template parameters to a variadic, and the IFTI parameters to
something else.
i.e.:
template foo(T...)
{
void foo(U...)(U args) {... }
}
foo!(int, char, bool)(1, 2, 3) -> foo!(int, char, bool)!(int, int,
int)(1, 2, 3);
I hope this clears it up a bit.
-Steve