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