11Ddoc
22
3+ $(COMMENT BE CAREFUL TO USE < AND > INSIDE CPPCODE2)
4+
35$(COMMUNITY Template Comparison,
46
57$(P C++ pioneered templates and template metaprogramming and has continued
@@ -23,8 +25,8 @@ templates based on the C++ experience.
2325
2426 $(TR
2527 $(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>` )
2830 )
2931
3032 $(TR
@@ -77,14 +79,15 @@ T foo(T i)
7779
7880 $(TR
7981 $(TD Constructor Templates)
80- $(TD No )
82+ $(TD Yes )
8183 $(TD Yes)
8284 )
8385
8486 $(TR
8587 $(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,
8891 such as this variable:
8992---
9093template Foo(T)
@@ -97,7 +100,14 @@ template Foo(T)
97100 $(B$(U C++98))$(BR)
98101 No, only classes and functions
99102 $(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:
101111$(CPPCODE2
102112template<class T>
103113constexpr T pi = T(3.1415926535897932385L);
@@ -133,7 +143,8 @@ MyFoo<unsigned> f;
133143
134144 $(TR
135145 $(TD Sequence Constructors)
136- $(TD No)
146+ $(TD No, use a
147+ $(DDSUBLINK spec/function, typesafe_variadic_functions, variadic parameter) instead)
137148 $(TD
138149 $(B$(U C++98))$(BR)
139150 No
@@ -142,7 +153,7 @@ MyFoo<unsigned> f;
142153$(CPPCODE2
143154template <class T>
144155class Foo {
145- Foo(std::initializer_list<T> );
156+ Foo(std::initializer_list<T> );
146157};
147158
148159Foo<double> f = { 1.2, 3.0, 6.8 };
@@ -197,15 +208,16 @@ template<> class factorial<1>
197208 based on Template Arguments)
198209 $(TD Yes:
199210---
200- template void foo(T)(T i)
211+ void foo(T)(T i)
201212{
202213 static if (can_fast_foo!(T))
203214 FastFoo f = fast_foo(i);
204215 else
205216 SlowFoo f = slow_foo(i);
206217 use_foo(f);
207218}
208-
219+ ---
220+ ---
209221class HashTable(T, int maxLength)
210222{
211223 static if (maxLength < 0xFFFE)
@@ -223,23 +235,23 @@ $(CPPCODE2
223235template<class T> void foo(T i)
224236{
225237 // 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);
228240};
229241
230242template<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>
233245 ::type CellIdx;
234246 CellIdx index;
235247};
236248)
237249 $(BR)$(B$(U C++17))$(BR)
238- Yes, but is limited to block scope:
250+ Yes, but it's limited to block scope:
239251$(CPPCODE2
240252template<class T> void foo(T i)
241253{
242- if constexpr (can_fast_foo<T> )
254+ if constexpr (can_fast_foo<T> )
243255 FastFoo foo = fast_foo(i);
244256 else
245257 SlowFoo foo = slow_foo(i);
@@ -248,7 +260,7 @@ template<class T> void foo(T i)
248260
249261template<class T, int maxLength> class HashTable {
250262 // $(ERROR cannot use 'if' outside of a function)
251- if constexpr (maxLength < 0xFFFE)
263+ if constexpr (maxLength < 0xFFFE)
252264 using CellIdx = ushort;
253265 else
254266 using CellIdx = uint;
@@ -259,8 +271,8 @@ template<class T, int maxLength> class HashTable {
259271 )
260272
261273 $(TR
262- $(TD Template Declarations (with no definition) )
263- $(TD No )
274+ $(TD Template Forward Declarations )
275+ $(TD Not necessary )
264276 $(TD Yes:
265277$(CPPCODE2
266278template<class T>
@@ -289,15 +301,23 @@ class Foo {
289301 class Bar { ... };
290302 static T foo(T t, U u) { ... }
291303};
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);
294306)
295307 )
296308 )
297309
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+
298316 $(TR
299317 $(TD Compile time execution of functions)
300318 $(TD $(DDSUBLINK spec/function, interpretation, Yes):
319+
320+ $(RUNNABLE_EXAMPLE_COMPILE
301321---
302322int factorial(int i)
303323{
@@ -306,8 +326,9 @@ int factorial(int i)
306326 else
307327 return i * factorial(i - 1);
308328}
309- static f = factorial(6);
329+ pragma(msg, factorial(6) );
310330---
331+ )
311332 )
312333 $(TD
313334 $(B$(U C++98))$(BR)
@@ -376,7 +397,7 @@ void foo()
376397
377398 $(TR
378399 $(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). )
380401 $(TD Yes:
381402$(CPPCODE2
382403template<double& D>
@@ -466,7 +487,7 @@ void foo()
466487 $(TD String Parameters)
467488 $(TD Yes:
468489---
469- void foo(char[] format)(int i)
490+ void foo(string format)(int i)
470491{
471492 writefln(format, i);
472493}
@@ -480,10 +501,10 @@ foo!("i = %s")(3);
480501 $(BR)$(B$(U C++17))$(BR)
481502 Only indirectly:
482503$(CPPCODE2
483- template <const char* >
504+ template <const char *str >
484505struct S {};
485506
486- S<"Foo"> foo1; $(ERROR A string literal argument is still illegal)
507+ S<"Foo"> foo1; // $(ERROR A string literal argument is still illegal)
487508const char foo_str[] = "foo";
488509S<foo_str> foo2; // Literal types are allowed, including arrays.
489510)
@@ -675,18 +696,17 @@ class Foo< Bar<T,U> >
675696
676697 $(TR
677698 $(TD Overloading Function Templates with Functions)
678- $(TD No, but the equivalent can be done with explicitly specialized
679- templates:
699+ $(TD Yes:
680700---
681701void foo(T)(T t) { }
682- void foo(T: int)(int t ) { }
702+ void foo(int i ) { }
683703---
684704 )
685705 $(TD Yes:
686706$(CPPCODE2
687707template<class T>
688- void foo(T i ) { }
689- void foo(int t ) { }
708+ void foo(T t ) { }
709+ void foo(int i ) { }
690710)
691711 )
692712 )
@@ -708,19 +728,18 @@ void foo(int t) { }
708728 $(TD Can extract arguments of
709729 template instance)
710730 $(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- }
719731
732+ $(RUNNABLE_EXAMPLE_COMPILE
733+ ---
720734struct Bar(T1, T2) { }
721735alias 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+ }
723741---
742+ )
724743 See $(DDSUBLINK spec/expression, IsExpression, is expressions).)
725744 $(TD No)
726745 )
@@ -947,7 +966,7 @@ Macros:
947966 NO1=<td class="compNo"><a href="$1">No</a></td>
948967 D_CODE = <pre class="d_code2">$0</pre>
949968 CPPCODE2 = <pre class="cppcode2">$0</pre>
950- ERROR = $(RED $(B error))
969+ ERROR = $(RED $(B error) $0 )
951970 SUBNAV=$(SUBNAV_ARTICLES)
952971META_KEYWORDS=D Programming Language, template metaprogramming,
953972variadic templates, type deduction, dependent base class
0 commit comments