blob: b84cfdae96f56046e665cc0b135dde0bc4e0a503 [file] [log] [blame]
Brian Silverman72890c22015-09-19 14:37:37 -04001namespace Eigen {
2
3/** \page TopicTemplateKeyword The template and typename keywords in C++
4
5There are two uses for the \c template and \c typename keywords in C++. One of them is fairly well known
6amongst programmers: to define templates. The other use is more obscure: to specify that an expression refers
7to a template function or a type. This regularly trips up programmers that use the %Eigen library, often
Austin Schuh189376f2018-12-20 22:11:15 +11008leading to error messages from the compiler that are difficult to understand, such as "expected expression" or
9"no match for operator<".
Brian Silverman72890c22015-09-19 14:37:37 -040010
11\eigenAutoToc
12
13
14\section TopicTemplateKeywordToDefineTemplates Using the template and typename keywords to define templates
15
16The \c template and \c typename keywords are routinely used to define templates. This is not the topic of this
17page as we assume that the reader is aware of this (otherwise consult a C++ book). The following example
18should illustrate this use of the \c template keyword.
19
20\code
21template <typename T>
22bool isPositive(T x)
23{
24 return x > 0;
25}
26\endcode
27
28We could just as well have written <tt>template &lt;class T&gt;</tt>; the keywords \c typename and \c class have the
29same meaning in this context.
30
31
32\section TopicTemplateKeywordExample An example showing the second use of the template keyword
33
34Let us illustrate the second use of the \c template keyword with an example. Suppose we want to write a
35function which copies all entries in the upper triangular part of a matrix into another matrix, while keeping
36the lower triangular part unchanged. A straightforward implementation would be as follows:
37
38<table class="example">
39<tr><th>Example:</th><th>Output:</th></tr>
40<tr><td>
41\include TemplateKeyword_simple.cpp
42</td>
43<td>
44\verbinclude TemplateKeyword_simple.out
45</td></tr></table>
46
47That works fine, but it is not very flexible. First, it only works with dynamic-size matrices of
48single-precision floats; the function \c copyUpperTriangularPart() does not accept static-size matrices or
49matrices with double-precision numbers. Second, if you use an expression such as
50<tt>mat.topLeftCorner(3,3)</tt> as the parameter \c src, then this is copied into a temporary variable of type
51MatrixXf; this copy can be avoided.
52
53As explained in \ref TopicFunctionTakingEigenTypes, both issues can be resolved by making
54\c copyUpperTriangularPart() accept any object of type MatrixBase. This leads to the following code:
55
56<table class="example">
57<tr><th>Example:</th><th>Output:</th></tr>
58<tr><td>
59\include TemplateKeyword_flexible.cpp
60</td>
61<td>
62\verbinclude TemplateKeyword_flexible.out
63</td></tr></table>
64
65The one line in the body of the function \c copyUpperTriangularPart() shows the second, more obscure use of
66the \c template keyword in C++. Even though it may look strange, the \c template keywords are necessary
67according to the standard. Without it, the compiler may reject the code with an error message like "no match
68for operator<".
69
70
71\section TopicTemplateKeywordExplanation Explanation
72
73The reason that the \c template keyword is necessary in the last example has to do with the rules for how
74templates are supposed to be compiled in C++. The compiler has to check the code for correct syntax at the
75point where the template is defined, without knowing the actual value of the template arguments (\c Derived1
Austin Schuh189376f2018-12-20 22:11:15 +110076and \c Derived2 in the example). That means that the compiler cannot know that <tt>dst.triangularView</tt> is
Brian Silverman72890c22015-09-19 14:37:37 -040077a member template and that the following &lt; symbol is part of the delimiter for the template
Austin Schuh189376f2018-12-20 22:11:15 +110078parameter. Another possibility would be that <tt>dst.triangularView</tt> is a member variable with the &lt;
Brian Silverman72890c22015-09-19 14:37:37 -040079symbol refering to the <tt>operator&lt;()</tt> function. In fact, the compiler should choose the second
Austin Schuh189376f2018-12-20 22:11:15 +110080possibility, according to the standard. If <tt>dst.triangularView</tt> is a member template (as in our case),
Brian Silverman72890c22015-09-19 14:37:37 -040081the programmer should specify this explicitly with the \c template keyword and write <tt>dst.template
Austin Schuh189376f2018-12-20 22:11:15 +110082triangularView</tt>.
Brian Silverman72890c22015-09-19 14:37:37 -040083
84The precise rules are rather complicated, but ignoring some subtleties we can summarize them as follows:
85- A <em>dependent name</em> is name that depends (directly or indirectly) on a template parameter. In the
86 example, \c dst is a dependent name because it is of type <tt>MatrixBase&lt;Derived1&gt;</tt> which depends
87 on the template parameter \c Derived1.
Austin Schuh189376f2018-12-20 22:11:15 +110088- If the code contains either one of the constructs <tt>xxx.yyy</tt> or <tt>xxx-&gt;yyy</tt> and \c xxx is a
Brian Silverman72890c22015-09-19 14:37:37 -040089 dependent name and \c yyy refers to a member template, then the \c template keyword must be used before
90 \c yyy, leading to <tt>xxx.template yyy</tt> or <tt>xxx-&gt;template yyy</tt>.
Austin Schuh189376f2018-12-20 22:11:15 +110091- If the code contains the construct <tt>xxx::yyy</tt> and \c xxx is a dependent name and \c yyy refers to a
92 member typedef, then the \c typename keyword must be used before the whole construct, leading to
Brian Silverman72890c22015-09-19 14:37:37 -040093 <tt>typename xxx::yyy</tt>.
94
95As an example where the \c typename keyword is required, consider the following code in \ref TutorialSparse
96for iterating over the non-zero entries of a sparse matrix type:
97
98\code
99SparseMatrixType mat(rows,cols);
100for (int k=0; k<mat.outerSize(); ++k)
101 for (SparseMatrixType::InnerIterator it(mat,k); it; ++it)
102 {
103 /* ... */
104 }
105\endcode
106
107If \c SparseMatrixType depends on a template parameter, then the \c typename keyword is required:
108
109\code
110template <typename T>
111void iterateOverSparseMatrix(const SparseMatrix<T>& mat;
112{
113 for (int k=0; k<m1.outerSize(); ++k)
114 for (typename SparseMatrix<T>::InnerIterator it(mat,k); it; ++it)
115 {
116 /* ... */
117 }
118}
119\endcode
120
121
122\section TopicTemplateKeywordResources Resources for further reading
123
124For more information and a fuller explanation of this topic, the reader may consult the following sources:
125- The book "C++ Template Metaprogramming" by David Abrahams and Aleksey Gurtovoy contains a very good
126 explanation in Appendix B ("The typename and template Keywords") which formed the basis for this page.
127- http://pages.cs.wisc.edu/~driscoll/typename.html
128- http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18
129- http://www.comeaucomputing.com/techtalk/templates/#templateprefix
130- http://www.comeaucomputing.com/techtalk/templates/#typename
131
132*/
133}