From 52b7e6dcc6d8fb4a07c0126a29ddf843daf5a95b Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Tue, 13 Feb 2018 17:51:33 +0000 Subject: [PATCH 1/5] Improve variadic function templates article Use sequence instead of tuple. Minor wording changes. Formatting tweaks. --- articles/variadic-function-templates.dd | 37 +++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/articles/variadic-function-templates.dd b/articles/variadic-function-templates.dd index 269fb2f06c..23d04a814a 100644 --- a/articles/variadic-function-templates.dd +++ b/articles/variadic-function-templates.dd @@ -155,7 +155,7 @@ void print(...) $(P It isn't elegant or the most efficient, but it does work. However it is not the recommended way to write variadic functions. - (It relies on the parameters _argptr and _arguments imported from core.vararg + (It relies on the parameters `_argptr` and `_arguments` imported from `core.vararg` which give a pointer to the values and their types, respectively.) ) @@ -180,18 +180,19 @@ void print(T, A...)(T t, A a) $(P There are two function templates. The first provides the degenerate case of no arguments, and a terminus for the recursion of the second. The second has two arguments: - t for the first value and a for the rest of the values. - A... says the parameter is a tuple, and implicit function - template instantiation will fill in A with the list of - all the types following t. So, print(7, 'a', 6.8) will - fill in int for T, and a tuple (char, double) for A. - The parameter a becomes an expression tuple of the arguments. + `t` for the first value and `a` for any remaining values. + `A...` says the parameter is a sequence, and $(I implicit function + template instantiation) will fill in `A` with all the types of any + arguments supplied following `t`. So, `print(7, 'a', 6.8)` will + fill in `int` for `T`, and a type sequence `(char, double)` for `A`. + The parameter `a` is an lvalue sequence of any + arguments supplied after `t`. ) - $(P The function works by printing the first parameter t, + $(P The function works by printing the first parameter `t`, and then recursively calling itself with the remaining arguments - a. The recursion terminates when there are no longer any - arguments by calling print()(). + `a`. The recursion terminates when there are no longer any + arguments by calling `print()()`. ) $(H4 The Static If Solution) @@ -213,18 +214,18 @@ void print(A...)(A a) } --- - $(P Tuples can be manipulated much like arrays. - So a.length resolves to the number of expressions - in the tuple a. a[0] gives the first expression - in the tuple. a[1 .. $] creates a new tuple - by slicing the original tuple. + $(P Sequences can be manipulated much like arrays. + So `a.length` resolves to the number of elements + in the sequence `a`. `a[0]` gives the first element + in the sequence. `a[1 .. $]` creates a new sequence + from any remaining elements in the original sequence. ) $(H4 The Foreach Solution) - $(P But since tuples can be manipulated like arrays, - we can use a foreach statement to 'loop' over - the tuple's expressions: + $(P But since sequences can be manipulated like arrays, + we can use a `foreach` statement to iterate over + the sequence's elements: ) --- From 16d0771e92d2c82502dc06d2b15dd4b716deb476 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 14 Feb 2018 13:05:41 +0000 Subject: [PATCH 2/5] Update for C++11 variadic templates --- articles/variadic-function-templates.dd | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/articles/variadic-function-templates.dd b/articles/variadic-function-templates.dd index 23d04a814a..90d7e1b4c7 100644 --- a/articles/variadic-function-templates.dd +++ b/articles/variadic-function-templates.dd @@ -22,8 +22,7 @@ $(CONSOLE ) $(P We'll explore how this can - be done in standard C++, followed by doing it using - the proposed variadic template C++ extension. + be done in C++. Then, we'll do it the various ways the D programming language makes possible. ) @@ -97,12 +96,9 @@ template<class T1, class T2, class T3> void print(T1 a1, T2 a2, T3 a3) compilation. ) -$(H4 The C++ Extension Solution) +$(H4 C++ Variadic Templates) - $(P Douglas Gregor has proposed a - variadic template scheme [1] - for C++ that solves these problems. - The result looks like: + $(P C++11 supports variadic templates: ) $(CCODE @@ -120,12 +116,6 @@ template<class T, class... U> void print(T a1, U... an) $(P It uses recursive function template instantiation to pick off the arguments one by one. A specialization with no arguments ends the recursion. - It's a neat and tidy solution, but with one glaring problem: - it's a proposed extension, which means it isn't part - of the C++ standard, may not get into the C++ standard - in its current form, may not get into the standard - in any form, and even if it does, it may be many, many - years before the feature is commonly implemented. ) $(H3 D Programming Language Solutions) @@ -162,7 +152,7 @@ void print(...) $(H4 Translating the Variadic C++ Solution into D) $(P Variadic templates in D enable a straightforward translation - of the proposed C++ variadic syntax: + of the C++11 variadic solution: ) --- From 0b5b60f6a066a6367f4641dd4410d477d0c8fc2e Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Mon, 19 Feb 2018 12:30:16 +0000 Subject: [PATCH 3/5] Add short TOC, remove now unused references section --- articles/variadic-function-templates.dd | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/articles/variadic-function-templates.dd b/articles/variadic-function-templates.dd index 90d7e1b4c7..10f1f17c72 100644 --- a/articles/variadic-function-templates.dd +++ b/articles/variadic-function-templates.dd @@ -2,6 +2,8 @@ Ddoc $(D_S Variadic Templates, +$(HEADERNAV_TOC) + $(P The problem statement is simple: write a function that takes an arbitrary number of values of arbitrary types, and print those values out one per line in a manner @@ -27,7 +29,7 @@ $(CONSOLE language makes possible. ) -$(H3 C++ Solutions) +$(H3 $(LNAME2 cpp-solutions, C++ Solutions)) $(H4 The Standard C++ Solution) @@ -118,7 +120,7 @@ template<class T, class... U> void print(T a1, U... an) A specialization with no arguments ends the recursion. ) -$(H3 D Programming Language Solutions) +$(H3 $(LNAME2 d-solutions, D Programming Language Solutions)) $(H4 The D Look Ma No Templates Solution) @@ -245,14 +247,6 @@ $(H3 Acknowledgments) ) -$(H3 References) - - $(OL - - $(LI $(LINK2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2080.pdf, Variadic Templates N2080)) - - ) - ) Macros: From 15069162528caeed3298be420eac0d3c919273d0 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Tue, 20 Feb 2018 13:15:50 +0000 Subject: [PATCH 4/5] Fix heading numbering --- articles/variadic-function-templates.dd | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/articles/variadic-function-templates.dd b/articles/variadic-function-templates.dd index 10f1f17c72..4909db6ea4 100644 --- a/articles/variadic-function-templates.dd +++ b/articles/variadic-function-templates.dd @@ -29,9 +29,9 @@ $(CONSOLE language makes possible. ) -$(H3 $(LNAME2 cpp-solutions, C++ Solutions)) +$(H2 $(LNAME2 cpp-solutions, C++ Solutions)) -$(H4 The Standard C++ Solution) +$(H3 The Overload Solution) $(P The straightforward way to do this in standard C++ is to use a series of function templates, one for @@ -98,7 +98,7 @@ template<class T1, class T2, class T3> void print(T1 a1, T2 a2, T3 a3) compilation. ) -$(H4 C++ Variadic Templates) +$(H3 C++ Variadic Templates) $(P C++11 supports variadic templates: ) @@ -120,9 +120,9 @@ template<class T, class... U> void print(T a1, U... an) A specialization with no arguments ends the recursion. ) -$(H3 $(LNAME2 d-solutions, D Programming Language Solutions)) +$(H2 $(LNAME2 d-solutions, D Programming Language Solutions)) -$(H4 The D Look Ma No Templates Solution) +$(H3 The D Look Ma No Templates Solution) $(P It is not practical to solve this problem in C++ without using templates. In D, one can because D supports typesafe @@ -151,7 +151,7 @@ void print(...) which give a pointer to the values and their types, respectively.) ) -$(H4 Translating the Variadic C++ Solution into D) +$(H3 Translating the Variadic C++ Solution into D) $(P Variadic templates in D enable a straightforward translation of the C++11 variadic solution: @@ -187,7 +187,7 @@ void print(T, A...)(T t, A a) arguments by calling `print()()`. ) -$(H4 The Static If Solution) +$(H3 The Static If Solution) $(P It would be nice to encapsulate all the logic into a single function. One way to do that is by using @@ -213,7 +213,7 @@ void print(A...)(A a) from any remaining elements in the original sequence. ) -$(H4 The Foreach Solution) +$(H3 The Foreach Solution) $(P But since sequences can be manipulated like arrays, we can use a `foreach` statement to iterate over From e7c3d8eb4097afb5efe9e61988a233a0b2ad5d7e Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Tue, 20 Feb 2018 13:16:28 +0000 Subject: [PATCH 5/5] Tweak D variadic example, add links --- articles/variadic-function-templates.dd | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/articles/variadic-function-templates.dd b/articles/variadic-function-templates.dd index 4909db6ea4..2fab984dd6 100644 --- a/articles/variadic-function-templates.dd +++ b/articles/variadic-function-templates.dd @@ -158,33 +158,37 @@ $(H3 Translating the Variadic C++ Solution into D) ) --- -void print()() +void print() { } void print(T, A...)(T t, A a) { + import std.stdio; writeln(t); print(a); } --- - $(P There are two function templates. The first provides the + $(P There are two overloads. The first provides the degenerate case of no arguments, and a terminus for the recursion of the second. The second has two arguments: `t` for the first value and `a` for any remaining values. - `A...` says the parameter is a sequence, and $(I implicit function - template instantiation) will fill in `A` with all the types of any + `A...` says the parameter is a sequence, and + $(GLOSSARY2 ifti, Implicit Function Template Instantiation) + will fill in `A` with all the types of any arguments supplied following `t`. So, `print(7, 'a', 6.8)` will fill in `int` for `T`, and a type sequence `(char, double)` for `A`. The parameter `a` is an lvalue sequence of any - arguments supplied after `t`. + arguments supplied after `t`. See + $(DDLINK articles/ctarguments, Compile-time Sequences, Compile-time Sequences) + for more information. ) $(P The function works by printing the first parameter `t`, and then recursively calling itself with the remaining arguments `a`. The recursion terminates when there are no longer any - arguments by calling `print()()`. + arguments by calling `print()`. ) $(H3 The Static If Solution)