Implicit Function Template Instantiation (IFTI) Question
Steven Schveighoffer
schveiguy at gmail.com
Mon Apr 27 17:40:06 UTC 2020
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
More information about the Digitalmars-d-learn
mailing list