Brian Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 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 |
Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 8 | leading to error messages from the compiler that are difficult to understand, such as "expected expression" or |
| 9 | "no match for operator<". |
Brian Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 10 | |
| 11 | \eigenAutoToc |
| 12 | |
| 13 | |
| 14 | \section TopicTemplateKeywordToDefineTemplates Using the template and typename keywords to define templates |
| 15 | |
| 16 | The \c template and \c typename keywords are routinely used to define templates. This is not the topic of this |
| 17 | page as we assume that the reader is aware of this (otherwise consult a C++ book). The following example |
| 18 | should illustrate this use of the \c template keyword. |
| 19 | |
| 20 | \code |
| 21 | template <typename T> |
| 22 | bool isPositive(T x) |
| 23 | { |
| 24 | return x > 0; |
| 25 | } |
| 26 | \endcode |
| 27 | |
| 28 | We could just as well have written <tt>template <class T></tt>; the keywords \c typename and \c class have the |
| 29 | same meaning in this context. |
| 30 | |
| 31 | |
| 32 | \section TopicTemplateKeywordExample An example showing the second use of the template keyword |
| 33 | |
| 34 | Let us illustrate the second use of the \c template keyword with an example. Suppose we want to write a |
| 35 | function which copies all entries in the upper triangular part of a matrix into another matrix, while keeping |
| 36 | the 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 | |
| 47 | That works fine, but it is not very flexible. First, it only works with dynamic-size matrices of |
| 48 | single-precision floats; the function \c copyUpperTriangularPart() does not accept static-size matrices or |
| 49 | matrices 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 |
| 51 | MatrixXf; this copy can be avoided. |
| 52 | |
| 53 | As 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 | |
| 65 | The one line in the body of the function \c copyUpperTriangularPart() shows the second, more obscure use of |
| 66 | the \c template keyword in C++. Even though it may look strange, the \c template keywords are necessary |
| 67 | according to the standard. Without it, the compiler may reject the code with an error message like "no match |
| 68 | for operator<". |
| 69 | |
| 70 | |
| 71 | \section TopicTemplateKeywordExplanation Explanation |
| 72 | |
| 73 | The reason that the \c template keyword is necessary in the last example has to do with the rules for how |
| 74 | templates are supposed to be compiled in C++. The compiler has to check the code for correct syntax at the |
| 75 | point where the template is defined, without knowing the actual value of the template arguments (\c Derived1 |
Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 76 | and \c Derived2 in the example). That means that the compiler cannot know that <tt>dst.triangularView</tt> is |
Brian Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 77 | a member template and that the following < symbol is part of the delimiter for the template |
Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 78 | parameter. Another possibility would be that <tt>dst.triangularView</tt> is a member variable with the < |
Brian Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 79 | symbol refering to the <tt>operator<()</tt> function. In fact, the compiler should choose the second |
Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 80 | possibility, according to the standard. If <tt>dst.triangularView</tt> is a member template (as in our case), |
Brian Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 81 | the programmer should specify this explicitly with the \c template keyword and write <tt>dst.template |
Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 82 | triangularView</tt>. |
Brian Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 83 | |
| 84 | The 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<Derived1></tt> which depends |
| 87 | on the template parameter \c Derived1. |
Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 88 | - If the code contains either one of the constructs <tt>xxx.yyy</tt> or <tt>xxx->yyy</tt> and \c xxx is a |
Brian Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 89 | 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->template yyy</tt>. |
Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 91 | - 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 Silverman | 72890c2 | 2015-09-19 14:37:37 -0400 | [diff] [blame] | 93 | <tt>typename xxx::yyy</tt>. |
| 94 | |
| 95 | As an example where the \c typename keyword is required, consider the following code in \ref TutorialSparse |
| 96 | for iterating over the non-zero entries of a sparse matrix type: |
| 97 | |
| 98 | \code |
| 99 | SparseMatrixType mat(rows,cols); |
| 100 | for (int k=0; k<mat.outerSize(); ++k) |
| 101 | for (SparseMatrixType::InnerIterator it(mat,k); it; ++it) |
| 102 | { |
| 103 | /* ... */ |
| 104 | } |
| 105 | \endcode |
| 106 | |
| 107 | If \c SparseMatrixType depends on a template parameter, then the \c typename keyword is required: |
| 108 | |
| 109 | \code |
| 110 | template <typename T> |
| 111 | void 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 | |
| 124 | For 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 | } |