1
1
Ddoc
2
2
3
+ $(COMMENT BE CAREFUL TO USE < AND > INSIDE CPPCODE2)
4
+
3
5
$(COMMUNITY Template Comparison,
4
6
5
7
$(P C++ pioneered templates and template metaprogramming and has continued
@@ -23,8 +25,8 @@ templates based on the C++ experience.
23
25
24
26
$(TR
25
27
$(TD Argument list delineation)
26
- $(TD Uses !( ), as in Foo!(int). $(BR)Can omit parens when the argument is a single lexical token: Foo!int)
27
- $(TD Uses < > as in Foo< int> )
28
+ $(TD Uses ` !( )` , as in ` Foo!(int)` . $(BR)Can omit parens when the argument is a single lexical token: ` Foo!int` )
29
+ $(TD Uses `< >` as in ` Foo< int>` )
28
30
)
29
31
30
32
$(TR
@@ -77,14 +79,15 @@ T foo(T i)
77
79
78
80
$(TR
79
81
$(TD Constructor Templates)
80
- $(TD No )
82
+ $(TD Yes )
81
83
$(TD Yes)
82
84
)
83
85
84
86
$(TR
85
87
$(TD Parameterize any Declaration)
86
- $(TD Yes, classes, functions, typedefs,
87
- variables, enums, etc. can be parameterized,
88
+ $(TD Yes, classes, functions, any
89
+ $(DDSUBLINK spec/declaration, alias, alias),
90
+ variables, any enum, etc. can be parameterized,
88
91
such as this variable:
89
92
---
90
93
template Foo(T)
@@ -97,7 +100,14 @@ template Foo(T)
97
100
$(B$(U C++98))$(BR)
98
101
No, only classes and functions
99
102
$(BR)$(B$(U C++11))$(BR)
100
- Yes:
103
+ Added `using` type aliases:
104
+ $(CPPCODE2
105
+ template<class T>
106
+ using ptr = T*;
107
+ ptr<int> p;
108
+ )
109
+ $(B$(U C++14))$(BR)
110
+ Added `constexpr` constant:
101
111
$(CPPCODE2
102
112
template<class T>
103
113
constexpr T pi = T(3.1415926535897932385L);
@@ -133,7 +143,8 @@ MyFoo<unsigned> f;
133
143
134
144
$(TR
135
145
$(TD Sequence Constructors)
136
- $(TD No)
146
+ $(TD No, use a
147
+ $(DDSUBLINK spec/function, typesafe_variadic_functions, variadic parameter) instead)
137
148
$(TD
138
149
$(B$(U C++98))$(BR)
139
150
No
@@ -142,7 +153,7 @@ MyFoo<unsigned> f;
142
153
$(CPPCODE2
143
154
template <class T>
144
155
class Foo {
145
- Foo(std::initializer_list<T> );
156
+ Foo(std::initializer_list<T> );
146
157
};
147
158
148
159
Foo<double> f = { 1.2, 3.0, 6.8 };
@@ -197,15 +208,16 @@ template<> class factorial<1>
197
208
based on Template Arguments)
198
209
$(TD Yes:
199
210
---
200
- template void foo(T)(T i)
211
+ void foo(T)(T i)
201
212
{
202
213
static if (can_fast_foo!(T))
203
214
FastFoo f = fast_foo(i);
204
215
else
205
216
SlowFoo f = slow_foo(i);
206
217
use_foo(f);
207
218
}
208
-
219
+ ---
220
+ ---
209
221
class HashTable(T, int maxLength)
210
222
{
211
223
static if (maxLength < 0xFFFE)
@@ -223,23 +235,23 @@ $(CPPCODE2
223
235
template<class T> void foo(T i)
224
236
{
225
237
// Differentiate using a
226
- // Helper< bool> specialization
227
- Helper< can_fast_foo<T>> ::use_foo(i);
238
+ // Helper< bool> specialization
239
+ Helper< can_fast_foo<T>> ::use_foo(i);
228
240
};
229
241
230
242
template<class T, int maxLength> class HashTable {
231
- typedef typename std::conditional<
232
- maxLength < 0xFFFE, uint16_t, uint32_t>
243
+ typedef typename std::conditional<
244
+ maxLength < 0xFFFE, uint16_t, uint32_t>
233
245
::type CellIdx;
234
246
CellIdx index;
235
247
};
236
248
)
237
249
$(BR)$(B$(U C++17))$(BR)
238
- Yes, but is limited to block scope:
250
+ Yes, but it's limited to block scope:
239
251
$(CPPCODE2
240
252
template<class T> void foo(T i)
241
253
{
242
- if constexpr (can_fast_foo<T> )
254
+ if constexpr (can_fast_foo<T> )
243
255
FastFoo foo = fast_foo(i);
244
256
else
245
257
SlowFoo foo = slow_foo(i);
@@ -248,7 +260,7 @@ template<class T> void foo(T i)
248
260
249
261
template<class T, int maxLength> class HashTable {
250
262
// $(ERROR cannot use 'if' outside of a function)
251
- if constexpr (maxLength < 0xFFFE)
263
+ if constexpr (maxLength < 0xFFFE)
252
264
using CellIdx = ushort;
253
265
else
254
266
using CellIdx = uint;
@@ -259,8 +271,8 @@ template<class T, int maxLength> class HashTable {
259
271
)
260
272
261
273
$(TR
262
- $(TD Template Declarations (with no definition) )
263
- $(TD No )
274
+ $(TD Template Forward Declarations )
275
+ $(TD Not necessary )
264
276
$(TD Yes:
265
277
$(CPPCODE2
266
278
template<class T>
@@ -289,15 +301,23 @@ class Foo {
289
301
class Bar { ... };
290
302
static T foo(T t, U u) { ... }
291
303
};
292
- Foo< int, long> ::bar b;
293
- return Foo< char, int> ::foo('c', 3);
304
+ Foo< int, long> ::bar b;
305
+ return Foo< char, int> ::foo('c', 3);
294
306
)
295
307
)
296
308
)
297
309
310
+ $(TR
311
+ $(TD Deducing `this` parameter type)
312
+ $(TD $(DDSUBLINK spec/template, template_this_parameter, Yes))
313
+ $(TD $(B$(U C++23))$(BR)Yes)
314
+ )
315
+
298
316
$(TR
299
317
$(TD Compile time execution of functions)
300
318
$(TD $(DDSUBLINK spec/function, interpretation, Yes):
319
+
320
+ $(RUNNABLE_EXAMPLE_COMPILE
301
321
---
302
322
int factorial(int i)
303
323
{
@@ -306,8 +326,9 @@ int factorial(int i)
306
326
else
307
327
return i * factorial(i - 1);
308
328
}
309
- static f = factorial(6);
329
+ pragma(msg, factorial(6) );
310
330
---
331
+ )
311
332
)
312
333
$(TD
313
334
$(B$(U C++98))$(BR)
@@ -376,7 +397,7 @@ void foo()
376
397
377
398
$(TR
378
399
$(TD Reference Parameters)
379
- $(TD No, D does not have a general reference type )
400
+ $(TD No, but an alias parameter can be used instead (see below). )
380
401
$(TD Yes:
381
402
$(CPPCODE2
382
403
template<double& D>
@@ -466,7 +487,7 @@ void foo()
466
487
$(TD String Parameters)
467
488
$(TD Yes:
468
489
---
469
- void foo(char[] format)(int i)
490
+ void foo(string format)(int i)
470
491
{
471
492
writefln(format, i);
472
493
}
@@ -480,10 +501,10 @@ foo!("i = %s")(3);
480
501
$(BR)$(B$(U C++17))$(BR)
481
502
Only indirectly:
482
503
$(CPPCODE2
483
- template <const char* >
504
+ template <const char *str >
484
505
struct S {};
485
506
486
- S<"Foo"> foo1; $(ERROR A string literal argument is still illegal)
507
+ S<"Foo"> foo1; // $(ERROR A string literal argument is still illegal)
487
508
const char foo_str[] = "foo";
488
509
S<foo_str> foo2; // Literal types are allowed, including arrays.
489
510
)
@@ -675,18 +696,17 @@ class Foo< Bar<T,U> >
675
696
676
697
$(TR
677
698
$(TD Overloading Function Templates with Functions)
678
- $(TD No, but the equivalent can be done with explicitly specialized
679
- templates:
699
+ $(TD Yes:
680
700
---
681
701
void foo(T)(T t) { }
682
- void foo(T: int)(int t ) { }
702
+ void foo(int i ) { }
683
703
---
684
704
)
685
705
$(TD Yes:
686
706
$(CPPCODE2
687
707
template<class T>
688
- void foo(T i ) { }
689
- void foo(int t ) { }
708
+ void foo(T t ) { }
709
+ void foo(int i ) { }
690
710
)
691
711
)
692
712
)
@@ -708,19 +728,18 @@ void foo(int t) { }
708
728
$(TD Can extract arguments of
709
729
template instance)
710
730
$(TD Yes:
711
- ---
712
- class Foo(T)
713
- {
714
- static if (is(T x : T!A, A...))
715
- {
716
- pragma(msg, A); // (int, float)
717
- }
718
- }
719
731
732
+ $(RUNNABLE_EXAMPLE_COMPILE
733
+ ---
720
734
struct Bar(T1, T2) { }
721
735
alias BarInst = Bar!(int, float);
722
- Foo!(BarInst) f;
736
+
737
+ static if (is(BarInst : Template!Args, alias Template, Args...))
738
+ {
739
+ pragma(msg, Args); // (int, float)
740
+ }
723
741
---
742
+ )
724
743
See $(DDSUBLINK spec/expression, IsExpression, is expressions).)
725
744
$(TD No)
726
745
)
@@ -947,7 +966,7 @@ Macros:
947
966
NO1=<td class="compNo"><a href="$1">No</a></td>
948
967
D_CODE = <pre class="d_code2">$0</pre>
949
968
CPPCODE2 = <pre class="cppcode2">$0</pre>
950
- ERROR = $(RED $(B error))
969
+ ERROR = $(RED $(B error) $0 )
951
970
SUBNAV=$(SUBNAV_ARTICLES)
952
971
META_KEYWORDS=D Programming Language, template metaprogramming,
953
972
variadic templates, type deduction, dependent base class
0 commit comments