@@ -905,6 +905,8 @@ $(H2 $(LNAME2 template_parameter_def_values, Template Parameter Default Values))
905
905
Foo!(uint); // instantiate Foo with T as uint, and U as uint*
906
906
------
907
907
908
+ $(P See also: $(RELATIVE_LINK2 function-default, Function Template Default Arguments).)
909
+
908
910
$(H2 $(LNAME2 implicit_template_properties, Eponymous Templates))
909
911
910
912
$(P If a template contains members whose name is the same as the
@@ -1034,7 +1036,7 @@ $(H2 $(LNAME2 function-templates, Function Templates))
1034
1036
$(P A function template to compute the square of type $(I T) is:)
1035
1037
1036
1038
------
1037
- T $(CODE_HIGHLIGHT Square )(T)(T t)
1039
+ T $(CODE_HIGHLIGHT square )(T)(T t)
1038
1040
{
1039
1041
return t * t;
1040
1042
}
@@ -1043,9 +1045,9 @@ $(H2 $(LNAME2 function-templates, Function Templates))
1043
1045
$(P It is lowered to:)
1044
1046
1045
1047
------
1046
- template $(CODE_HIGHLIGHT Square )(T)
1048
+ template $(CODE_HIGHLIGHT square )(T)
1047
1049
{
1048
- T $(CODE_HIGHLIGHT Square )(T t)
1050
+ T $(CODE_HIGHLIGHT square )(T t)
1049
1051
{
1050
1052
return t * t;
1051
1053
}
@@ -1056,50 +1058,52 @@ $(H2 $(LNAME2 function-templates, Function Templates))
1056
1058
!($(I TemplateArgumentList)):)
1057
1059
1058
1060
----
1059
- writefln("The square of %s is %s", 3, Square !(int)(3));
1061
+ writefln("The square of %s is %s", 3, square !(int)(3));
1060
1062
----
1061
1063
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:)
1064
1069
1065
1070
----
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
1067
1077
----
1068
1078
1079
+ $(P Type parameter deduction is not influenced by the order of function
1080
+ arguments.
1081
+ )
1082
+
1069
1083
$(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
1071
1085
parameters from left to right, and the rest of the parameters are then deduced
1072
1086
from the function arguments.
1073
1087
)
1074
1088
1075
- $(P The process of deducing template type parameters from function arguments
1076
- is called Implicit Function Template Instantiation (IFTI).
1077
- )
1078
-
1079
1089
$(P Function template type parameters that are to be implicitly
1080
1090
deduced may not have specializations:)
1081
1091
1082
1092
------
1083
- void $(CODE_HIGHLIGHT Foo )(T : T*)(T t) { ... }
1093
+ void $(CODE_HIGHLIGHT foo )(T : T*)(T t) { ... }
1084
1094
1085
1095
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
1088
1098
------
1089
1099
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))
1098
1101
1099
1102
$(P If template type parameters match the literal expressions on function arguments,
1100
1103
the deduced types may consider narrowing conversions of them.
1101
1104
)
1102
1105
1106
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
1103
1107
------
1104
1108
void foo(T)(T v) { pragma(msg, "in foo, T = ", T); }
1105
1109
void bar(T)(T v, T[] a) { pragma(msg, "in bar, T = ", T); }
@@ -1119,11 +1123,12 @@ $(H2 $(LNAME2 function-templates, Function Templates))
1119
1123
// and the integer literal 1 is implicitly convertible to double.
1120
1124
// then T will be deduced to double.
1121
1125
------
1122
-
1126
+ )
1123
1127
1124
1128
$(P The deduced type parameter for dynamic array and pointer arguments
1125
1129
has an unqualified head:)
1126
1130
1131
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
1127
1132
------
1128
1133
void foo(T)(T arg) { pragma(msg, T); }
1129
1134
@@ -1141,23 +1146,38 @@ $(H2 $(LNAME2 function-templates, Function Templates))
1141
1146
foo(cptr); // T == const(int)*
1142
1147
foo(iptr); // T == immutable(int)*
1143
1148
------
1144
-
1145
- $(P Type parameter deduction is not influenced by the order of function
1146
- arguments.
1147
1149
)
1148
1150
1151
+ $(H3 $(LNAME2 return-deduction, Return Type Deduction))
1152
+
1149
1153
$(P Function templates can have their return types deduced based on the
1150
1154
$(GLINK2 statement, ReturnStatement)s in the function, just as with
1151
1155
normal functions.
1152
1156
See $(DDSUBLINK function, auto-functions, Auto Functions).
1153
1157
)
1154
1158
1159
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
1155
1160
---
1156
- auto $(CODE_HIGHLIGHT Square) (T)(T t)
1161
+ auto square (T)(T t)
1157
1162
{
1158
1163
return t * t;
1159
1164
}
1165
+
1166
+ auto i = square(2);
1167
+ static assert(is(typeof(i) == int));
1160
1168
---
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
+ ------
1161
1181
1162
1182
$(P Variadic Function Templates can have parameters with default values.
1163
1183
These parameters are always set to their default value in case of IFTI.
@@ -1171,8 +1191,9 @@ $(H2 $(LNAME2 function-templates, Function Templates))
1171
1191
writeln(file, " ", t);
1172
1192
return T.length;
1173
1193
}
1194
+
1174
1195
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
1176
1197
---
1177
1198
)
1178
1199
0 commit comments