Skip to content

Commit 4b10ebd

Browse files
authored
[spec/template.dd] Improve docs (#3173)
* [spec/template.dd] Improve docs Add *Template Declarations* heading. Fix: Value parameters are not limited to int, float, string. Under *Explicit Instantiation*, add *Common Instantiation* subheading and move paragraph (about multiple template with the same) name above it. Add *Type Sequence Deduction* subheading of *Sequence Parameters*. Move *Template Constructors* below *Aggregate Templates* section. * Fix multi-module example formatting * Add *Template Instantiation* heading Rename parameter deduction heading. * Move ConstructorTemplate below FunctionTemplate * Add note about using short syntax instead of template block * Move 'IFTI vs static if' section to IFTI & add Restrictions subheading Also tweak eponymous templates paragraph. Add links. * Undo *Parameter Type Deduction* change, will be done in another PR * Single member templates are usually written with short syntax * Move paragraph about overloaded templates to TemplateDeclaration Change arguments -> parameters * Tweak links * Add example for template type parameter in TemplateDeclaration Tweak wording of other parameter kinds. * Alias parameters can take local symbols * Tweak sentence about value parameters & restore CT specialization * Tweak TemplateDeclaration docs & mention eponymous templates * Remove *Template Instantiation* changes (for another PR)
1 parent f9ac040 commit 4b10ebd

File tree

1 file changed

+76
-51
lines changed

1 file changed

+76
-51
lines changed

spec/template.dd

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ $(SPEC_S Templates,
44

55
$(HEADERNAV_TOC)
66

7+
$(H2 $(LNAME2 declarations, Template Declarations))
8+
79
$(P Templates are D's approach to generic programming.
8-
Templates are defined with a $(I TemplateDeclaration):
10+
Templates can be defined with a $(I TemplateDeclaration):
911
)
1012

1113
$(GRAMMAR
@@ -28,21 +30,27 @@ $(GNAME TemplateParameter):
2830
$(GLINK TemplateThisParameter)
2931
)
3032

31-
$(P The body of the $(I TemplateDeclaration) must be syntactically correct
33+
$(P The *DeclDefs* body of the template must be syntactically correct
3234
even if never instantiated. Semantic analysis is not done until
33-
instantiated. A template forms its own scope, and the template
34-
body can contain classes, structs, types, enums, variables,
35-
functions, and other templates.
35+
instantiation. A template forms its own scope, and the template
36+
body can contain declarations such as classes, structs, types,
37+
enums, variables, functions, and other templates.
3638
)
3739

38-
$(P Template parameters can be types, values, symbols, or sequences.
39-
Types can be any type.
40-
Value parameters must be of an integral type, floating point
41-
type, or string type and
42-
specializations for them must resolve to an integral constant,
43-
floating point constant, null, or a string literal.
44-
Symbols can be any non-local symbol.
45-
Sequences can contain zero or more types, values or symbols.
40+
$(P Template parameters can take types, values, symbols, or sequences.
41+
Type parameters can take any type.)
42+
43+
---
44+
template t(T) // declare type parameter T
45+
{
46+
T v; // declare a member variable of type T within template t
47+
}
48+
---
49+
50+
$(P Value parameters can take any expression which can be statically
51+
evaluated at compile time.
52+
Alias parameters can take almost any symbol.
53+
Sequence parameters can take zero or more types, values or symbols.
4654
)
4755

4856
$(P Template parameter specializations
@@ -53,6 +61,19 @@ $(GNAME TemplateParameter):
5361
$(I TemplateParameter) in case one is not supplied.
5462
)
5563

64+
$(P If multiple templates with the same $(I Identifier) are
65+
declared, they are distinct if they have different parameters
66+
or are differently specialized.
67+
)
68+
69+
$(P If a template has a member which has the same identifier as the
70+
template, the template is an
71+
$(RELATIVE_LINK2 implicit_template_properties, Eponymous Template).
72+
`template` declarations with one eponymous member are usually
73+
written as specific $(RELATIVE_LINK2 aggregate_templates, short syntax)
74+
template declarations instead.)
75+
76+
5677
$(H2 $(LNAME2 explicit_tmp_instantiation, Explicit Template Instantiation))
5778

5879
$(P Templates are explicitly instantiated with:
@@ -159,11 +180,6 @@ $(GNAME TemplateSingleArgument):
159180
static assert(is(TFoo!(3) == TFoo!(3u)));
160181
-----
161182

162-
$(P If multiple templates with the same $(I Identifier) are
163-
declared, they are distinct if they have a different number of
164-
arguments or are differently specialized.
165-
)
166-
167183
$(H3 $(LNAME2 copy_example, Practical Example))
168184

169185
$(P A simple generic copy template would be:)
@@ -463,8 +479,8 @@ $(GNAME TemplateValueParameterDefault):
463479
$(D =) $(GLINK2 expression, SpecialKeyword)
464480
)
465481

466-
$(P Template value parameter types can be any type which can
467-
be statically initialized at compile time.
482+
$(P A template value parameter can take an argument of any expression which can
483+
be statically evaluated at compile time.
468484
Template value arguments can be integer values, floating point values,
469485
nulls, string values, array literals of template value arguments,
470486
associative array literals of template value arguments,
@@ -485,6 +501,9 @@ $(GNAME TemplateValueParameterDefault):
485501
-----
486502
)
487503

504+
$(P Any specialization or default expression provided must be evaluatable
505+
at compile-time.)
506+
488507
$(P This example of template foo has a value parameter that
489508
is specialized for 10:)
490509

@@ -820,6 +839,8 @@ $(GNAME TemplateSequenceParameter):
820839
to dynamically change, add, or remove elements either at compile-time or run-time.
821840
)
822841

842+
$(H3 $(LNAME2 typeseq_deduction, Type Sequence Deduction))
843+
823844
$(P Type sequences can be deduced from the trailing parameters
824845
of an $(RELATIVE_LINK2 ifti, implicitly instantiated) function template:)
825846

@@ -940,7 +961,8 @@ $(H2 $(LNAME2 implicit_template_properties, Eponymous Templates))
940961
}
941962
------
942963

943-
$(P Using functions and more types than the template:)
964+
$(P The following example has more than one eponymous member and uses
965+
$(RELATIVE_LINK2 ifti, Implicit Function Template Instantiation):)
944966

945967
------
946968
template foo(S, T)
@@ -957,36 +979,7 @@ $(H2 $(LNAME2 implicit_template_properties, Eponymous Templates))
957979
}
958980
------
959981

960-
$(P When the template parameters must be deduced, the eponymous members
961-
can't rely on a $(LINK2 version.html#StaticIfCondition, `static if`)
962-
condition since the deduction relies on how the in members are used:)
963-
964-
------
965-
template foo(T)
966-
{
967-
static if (is(T)) // T is not yet known...
968-
void foo(T t) {} // T is deduced from the member usage
969-
}
970-
971-
void main()
972-
{
973-
foo(0); // Error: cannot deduce function from argument types
974-
foo!int(0); // Ok since no deduction necessary
975-
}
976-
------
977-
978-
$(H2 $(LNAME2 template_ctors, Template Constructors))
979-
980-
$(GRAMMAR
981-
$(GNAME ConstructorTemplate):
982-
$(D this) $(GLINK TemplateParameters) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) $(GLINK Constraint)$(OPT) $(D :)
983-
$(D this) $(GLINK TemplateParameters) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) $(GLINK Constraint)$(OPT) $(GLINK2 function, FunctionBody)
984-
)
985-
986-
$(P Templates can be used to form constructors for classes and structs.
987-
)
988-
989-
$(H2 $(LNAME2 aggregate_templates, Aggregate Templates))
982+
$(H2 $(LNAME2 aggregate_templates, Aggregate Type Templates))
990983

991984
$(GRAMMAR
992985
$(GNAME ClassTemplateDeclaration):
@@ -1103,6 +1096,8 @@ $(H3 $(LNAME2 ifti, Implicit Function Template Instantiation (IFTI)))
11031096
from the function arguments.
11041097
)
11051098

1099+
$(H4 $(LNAME2 ifti-restrictions, Restrictions))
1100+
11061101
$(P Function template type parameters that are to be implicitly
11071102
deduced may not have specializations:)
11081103

@@ -1114,6 +1109,25 @@ $(H3 $(LNAME2 ifti, Implicit Function Template Instantiation (IFTI)))
11141109
foo(&y); // error, T has specialization
11151110
------
11161111

1112+
$(P When the template parameters must be deduced, the
1113+
$(RELATIVE_LINK2 implicit_template_properties, eponymous members)
1114+
can't rely on a $(LINK2 version.html#StaticIfCondition, `static if`)
1115+
condition since the deduction relies on how the members are used:)
1116+
1117+
------
1118+
template foo(T)
1119+
{
1120+
static if (is(T)) // T is not yet known...
1121+
void foo(T t) {} // T is deduced from the member usage
1122+
}
1123+
1124+
void main()
1125+
{
1126+
foo(0); // Error: cannot deduce function from argument types
1127+
foo!int(0); // Ok since no deduction necessary
1128+
}
1129+
------
1130+
11171131
$(H4 $(LNAME2 ifti-conversions, Type Conversions))
11181132

11191133
$(P If template type parameters match the literal expressions on function arguments,
@@ -1214,6 +1228,17 @@ $(H3 $(LNAME2 function-default, Default Arguments))
12141228
---
12151229
)
12161230

1231+
$(H2 $(LNAME2 template_ctors, Template Constructors))
1232+
1233+
$(GRAMMAR
1234+
$(GNAME ConstructorTemplate):
1235+
$(D this) $(GLINK TemplateParameters) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) $(GLINK Constraint)$(OPT) $(D :)
1236+
$(D this) $(GLINK TemplateParameters) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) $(GLINK Constraint)$(OPT) $(GLINK2 function, FunctionBody)
1237+
)
1238+
1239+
$(P Templates can be used to form constructors for classes and structs.
1240+
)
1241+
12171242
$(H2 $(LNAME2 variable-template, Enum & Variable Templates))
12181243

12191244
$(P Like aggregates and functions, manifest constant and variable

0 commit comments

Comments
 (0)