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