Skip to content

Commit 145399e

Browse files
authored
Merge pull request #2824 from ntrel/func-template
[spec/template.dd] Improve Function Templates section
2 parents 29df268 + 72c153a commit 145399e

File tree

2 files changed

+51
-30
lines changed

2 files changed

+51
-30
lines changed

glossary.dd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ $(DL
5656
$(DD Refers to the ability to instantiate a template function
5757
without having to explicitly pass in the types to the template.
5858
Instead, the types are inferred automatically from the types of the
59-
runtime arguments.)
59+
runtime arguments. See $(LINK2 spec/template.html#ifti, spec) for details.)
6060

6161
$(DT Illegal)
6262
$(DD A code construct is illegal if it does not conform to the

spec/template.dd

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,8 @@ $(H2 $(LNAME2 template_parameter_def_values, Template Parameter Default Values))
905905
Foo!(uint); // instantiate Foo with T as uint, and U as uint*
906906
------
907907

908+
$(P See also: $(RELATIVE_LINK2 function-default, Function Template Default Arguments).)
909+
908910
$(H2 $(LNAME2 implicit_template_properties, Eponymous Templates))
909911

910912
$(P If a template contains members whose name is the same as the
@@ -1034,7 +1036,7 @@ $(H2 $(LNAME2 function-templates, Function Templates))
10341036
$(P A function template to compute the square of type $(I T) is:)
10351037

10361038
------
1037-
T $(CODE_HIGHLIGHT Square)(T)(T t)
1039+
T $(CODE_HIGHLIGHT square)(T)(T t)
10381040
{
10391041
return t * t;
10401042
}
@@ -1043,9 +1045,9 @@ $(H2 $(LNAME2 function-templates, Function Templates))
10431045
$(P It is lowered to:)
10441046

10451047
------
1046-
template $(CODE_HIGHLIGHT Square)(T)
1048+
template $(CODE_HIGHLIGHT square)(T)
10471049
{
1048-
T $(CODE_HIGHLIGHT Square)(T t)
1050+
T $(CODE_HIGHLIGHT square)(T t)
10491051
{
10501052
return t * t;
10511053
}
@@ -1056,50 +1058,52 @@ $(H2 $(LNAME2 function-templates, Function Templates))
10561058
!($(I TemplateArgumentList)):)
10571059

10581060
----
1059-
writefln("The square of %s is %s", 3, Square!(int)(3));
1061+
writefln("The square of %s is %s", 3, square!(int)(3));
10601062
----
10611063

1062-
or implicitly, where the $(I TemplateArgumentList) is deduced
1063-
from the types of the function arguments:
1064+
$(H3 $(LNAME2 ifti, Implicit Function Template Instantiation (IFTI)))
1065+
1066+
$(P Function templates can be $(I implicitly) instantiated if the
1067+
$(I TemplateArgumentList) is deducible from the types of the
1068+
function arguments:)
10641069

10651070
----
1066-
writefln("The square of %s is %s", 3, Square(3)); // T is deduced to be int
1071+
T square(T)(T t)
1072+
{
1073+
return t * t;
1074+
}
1075+
1076+
writefln("The square of %s is %s", 3, square(3)); // T is deduced to be int
10671077
----
10681078

1079+
$(P Type parameter deduction is not influenced by the order of function
1080+
arguments.
1081+
)
1082+
10691083
$(P If there are fewer arguments supplied in the $(I TemplateArgumentList)
1070-
than parameters in the $(I TemplateParameterList), the arguments fulfill
1084+
than parameters in the $(I TemplateParameterList), the arguments fill
10711085
parameters from left to right, and the rest of the parameters are then deduced
10721086
from the function arguments.
10731087
)
10741088

1075-
$(P The process of deducing template type parameters from function arguments
1076-
is called Implicit Function Template Instantiation (IFTI).
1077-
)
1078-
10791089
$(P Function template type parameters that are to be implicitly
10801090
deduced may not have specializations:)
10811091

10821092
------
1083-
void $(CODE_HIGHLIGHT Foo)(T : T*)(T t) { ... }
1093+
void $(CODE_HIGHLIGHT foo)(T : T*)(T t) { ... }
10841094

10851095
int x,y;
1086-
Foo!(int*)(x); // ok, T is not deduced from function argument
1087-
Foo(&y); // error, T has specialization
1096+
foo!(int*)(x); // ok, T is not deduced from function argument
1097+
foo(&y); // error, T has specialization
10881098
------
10891099

1090-
$(P Template arguments not implicitly deduced can have default values:)
1091-
1092-
------
1093-
void $(CODE_HIGHLIGHT Foo)(T, U=T*)(T t) { U p; ... }
1094-
1095-
int x;
1096-
Foo(x); // T is int, U is int*
1097-
------
1100+
$(H4 $(LNAME2 ifti-conversions, Type Conversions))
10981101

10991102
$(P If template type parameters match the literal expressions on function arguments,
11001103
the deduced types may consider narrowing conversions of them.
11011104
)
11021105

1106+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
11031107
------
11041108
void foo(T)(T v) { pragma(msg, "in foo, T = ", T); }
11051109
void bar(T)(T v, T[] a) { pragma(msg, "in bar, T = ", T); }
@@ -1119,11 +1123,12 @@ $(H2 $(LNAME2 function-templates, Function Templates))
11191123
// and the integer literal 1 is implicitly convertible to double.
11201124
// then T will be deduced to double.
11211125
------
1122-
1126+
)
11231127

11241128
$(P The deduced type parameter for dynamic array and pointer arguments
11251129
has an unqualified head:)
11261130

1131+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
11271132
------
11281133
void foo(T)(T arg) { pragma(msg, T); }
11291134

@@ -1141,23 +1146,38 @@ $(H2 $(LNAME2 function-templates, Function Templates))
11411146
foo(cptr); // T == const(int)*
11421147
foo(iptr); // T == immutable(int)*
11431148
------
1144-
1145-
$(P Type parameter deduction is not influenced by the order of function
1146-
arguments.
11471149
)
11481150

1151+
$(H3 $(LNAME2 return-deduction, Return Type Deduction))
1152+
11491153
$(P Function templates can have their return types deduced based on the
11501154
$(GLINK2 statement, ReturnStatement)s in the function, just as with
11511155
normal functions.
11521156
See $(DDSUBLINK function, auto-functions, Auto Functions).
11531157
)
11541158

1159+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
11551160
---
1156-
auto $(CODE_HIGHLIGHT Square)(T)(T t)
1161+
auto square(T)(T t)
11571162
{
11581163
return t * t;
11591164
}
1165+
1166+
auto i = square(2);
1167+
static assert(is(typeof(i) == int));
11601168
---
1169+
)
1170+
1171+
$(H3 $(LNAME2 function-default, Default Arguments))
1172+
1173+
$(P Template arguments not implicitly deduced can have default values:)
1174+
1175+
------
1176+
void $(CODE_HIGHLIGHT foo)(T, U=T*)(T t) { U p; ... }
1177+
1178+
int x;
1179+
foo(x); // T is int, U is int*
1180+
------
11611181

11621182
$(P Variadic Function Templates can have parameters with default values.
11631183
These parameters are always set to their default value in case of IFTI.
@@ -1171,8 +1191,9 @@ $(H2 $(LNAME2 function-templates, Function Templates))
11711191
writeln(file, " ", t);
11721192
return T.length;
11731193
}
1194+
11741195
assert(fun(1, "foo") == 2); // uses IFTI
1175-
assert(fun!int(1, "foo") == 1); // no IFTI
1196+
assert(fun!int(1, "filename") == 1); // no IFTI
11761197
---
11771198
)
11781199

0 commit comments

Comments
 (0)