|
|
namespace Eigen { |
|
|
|
|
|
/** \page TopicTemplateKeyword The template and typename keywords in C++ |
|
|
|
|
|
There are two uses for the \c template and \c typename keywords in C++. One of them is fairly well known |
|
|
amongst programmers: to define templates. The other use is more obscure: to specify that an expression refers |
|
|
to a template function or a type. This regularly trips up programmers that use the %Eigen library, often |
|
|
leading to error messages from the compiler that are difficult to understand, such as "expected expression" or |
|
|
"no match for operator<". |
|
|
|
|
|
\eigenAutoToc |
|
|
|
|
|
|
|
|
\section TopicTemplateKeywordToDefineTemplates Using the template and typename keywords to define templates |
|
|
|
|
|
The \c template and \c typename keywords are routinely used to define templates. This is not the topic of this |
|
|
page as we assume that the reader is aware of this (otherwise consult a C++ book). The following example |
|
|
should illustrate this use of the \c template keyword. |
|
|
|
|
|
\code |
|
|
template <typename T> |
|
|
bool isPositive(T x) |
|
|
{ |
|
|
return x > 0; |
|
|
} |
|
|
\endcode |
|
|
|
|
|
We could just as well have written <tt>template <class T></tt>; the keywords \c typename and \c class have the |
|
|
same meaning in this context. |
|
|
|
|
|
|
|
|
\section TopicTemplateKeywordExample An example showing the second use of the template keyword |
|
|
|
|
|
Let us illustrate the second use of the \c template keyword with an example. Suppose we want to write a |
|
|
function which copies all entries in the upper triangular part of a matrix into another matrix, while keeping |
|
|
the lower triangular part unchanged. A straightforward implementation would be as follows: |
|
|
|
|
|
<table class="example"> |
|
|
<tr><th>Example:</th><th>Output:</th></tr> |
|
|
<tr><td> |
|
|
\include TemplateKeyword_simple.cpp |
|
|
</td> |
|
|
<td> |
|
|
\verbinclude TemplateKeyword_simple.out |
|
|
</td></tr></table> |
|
|
|
|
|
That works fine, but it is not very flexible. First, it only works with dynamic-size matrices of |
|
|
single-precision floats; the function \c copyUpperTriangularPart() does not accept static-size matrices or |
|
|
matrices with double-precision numbers. Second, if you use an expression such as |
|
|
<tt>mat.topLeftCorner(3,3)</tt> as the parameter \c src, then this is copied into a temporary variable of type |
|
|
MatrixXf; this copy can be avoided. |
|
|
|
|
|
As explained in \ref TopicFunctionTakingEigenTypes, both issues can be resolved by making |
|
|
\c copyUpperTriangularPart() accept any object of type MatrixBase. This leads to the following code: |
|
|
|
|
|
<table class="example"> |
|
|
<tr><th>Example:</th><th>Output:</th></tr> |
|
|
<tr><td> |
|
|
\include TemplateKeyword_flexible.cpp |
|
|
</td> |
|
|
<td> |
|
|
\verbinclude TemplateKeyword_flexible.out |
|
|
</td></tr></table> |
|
|
|
|
|
The one line in the body of the function \c copyUpperTriangularPart() shows the second, more obscure use of |
|
|
the \c template keyword in C++. Even though it may look strange, the \c template keywords are necessary |
|
|
according to the standard. Without it, the compiler may reject the code with an error message like "no match |
|
|
for operator<". |
|
|
|
|
|
|
|
|
\section TopicTemplateKeywordExplanation Explanation |
|
|
|
|
|
The reason that the \c template keyword is necessary in the last example has to do with the rules for how |
|
|
templates are supposed to be compiled in C++. The compiler has to check the code for correct syntax at the |
|
|
point where the template is defined, without knowing the actual value of the template arguments (\c Derived1 |
|
|
and \c Derived2 in the example). That means that the compiler cannot know that <tt>dst.triangularView</tt> is |
|
|
a member template and that the following < symbol is part of the delimiter for the template |
|
|
parameter. Another possibility would be that <tt>dst.triangularView</tt> is a member variable with the < |
|
|
symbol refering to the <tt>operator<()</tt> function. In fact, the compiler should choose the second |
|
|
possibility, according to the standard. If <tt>dst.triangularView</tt> is a member template (as in our case), |
|
|
the programmer should specify this explicitly with the \c template keyword and write <tt>dst.template |
|
|
triangularView</tt>. |
|
|
|
|
|
The precise rules are rather complicated, but ignoring some subtleties we can summarize them as follows: |
|
|
- A <em>dependent name</em> is name that depends (directly or indirectly) on a template parameter. In the |
|
|
example, \c dst is a dependent name because it is of type <tt>MatrixBase<Derived1></tt> which depends |
|
|
on the template parameter \c Derived1. |
|
|
- If the code contains either one of the constructs <tt>xxx.yyy</tt> or <tt>xxx->yyy</tt> and \c xxx is a |
|
|
dependent name and \c yyy refers to a member template, then the \c template keyword must be used before |
|
|
\c yyy, leading to <tt>xxx.template yyy</tt> or <tt>xxx->template yyy</tt>. |
|
|
- If the code contains the construct <tt>xxx::yyy</tt> and \c xxx is a dependent name and \c yyy refers to a |
|
|
member typedef, then the \c typename keyword must be used before the whole construct, leading to |
|
|
<tt>typename xxx::yyy</tt>. |
|
|
|
|
|
As an example where the \c typename keyword is required, consider the following code in \ref TutorialSparse |
|
|
for iterating over the non-zero entries of a sparse matrix type: |
|
|
|
|
|
\code |
|
|
SparseMatrixType mat(rows,cols); |
|
|
for (int k=0; k<mat.outerSize(); ++k) |
|
|
for (SparseMatrixType::InnerIterator it(mat,k); it; ++it) |
|
|
{ |
|
|
/* ... */ |
|
|
} |
|
|
\endcode |
|
|
|
|
|
If \c SparseMatrixType depends on a template parameter, then the \c typename keyword is required: |
|
|
|
|
|
\code |
|
|
template <typename T> |
|
|
void iterateOverSparseMatrix(const SparseMatrix<T>& mat; |
|
|
{ |
|
|
for (int k=0; k<m1.outerSize(); ++k) |
|
|
for (typename SparseMatrix<T>::InnerIterator it(mat,k); it; ++it) |
|
|
{ |
|
|
/* ... */ |
|
|
} |
|
|
} |
|
|
\endcode |
|
|
|
|
|
|
|
|
\section TopicTemplateKeywordResources Resources for further reading |
|
|
|
|
|
For more information and a fuller explanation of this topic, the reader may consult the following sources: |
|
|
- The book "C++ Template Metaprogramming" by David Abrahams and Aleksey Gurtovoy contains a very good |
|
|
explanation in Appendix B ("The typename and template Keywords") which formed the basis for this page. |
|
|
- http://pages.cs.wisc.edu/~driscoll/typename.html |
|
|
- http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18 |
|
|
- http://www.comeaucomputing.com/techtalk/templates/#templateprefix |
|
|
- http://www.comeaucomputing.com/techtalk/templates/#typename |
|
|
|
|
|
*/ |
|
|
} |
|
|
|