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.
Table of contents
- \ref TopicTemplateKeywordToDefineTemplates
- \ref TopicTemplateKeywordExample
- \ref TopicTemplateKeywordExplanation
- \ref TopicTemplateKeywordResources
\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
bool isPositive(T x)
{
return x > 0;
}
\endcode
We could just as well have written template <class T>; 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:
Example:
Output:
\include TemplateKeyword_simple.cpp
\verbinclude TemplateKeyword_simple.out
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
mat.topLeftCorner(3,3) 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:
Example:
Output:
\include TemplateKeyword_flexible.cpp
\verbinclude TemplateKeyword_flexible.out
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 dst.triangularPart is
a member template and that the following < symbol is part of the delimiter for the template
parameter. Another possibility would be that dst.triangularPart is a member variable with the <
symbol refering to the operator<() function. In fact, the compiler should choose the second
possibility, according to the standard. If dst.triangularPart is a member template (as in our case),
the programmer should specify this explicitly with the \c template keyword and write dst.template
triangularPart.
The precise rules are rather complicated, but ignoring some subtleties we can summarize them as follows:
- A dependent name 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 MatrixBase<Derived1> which depends
on the template parameter \c Derived1.
- If the code contains either one of the contructions xxx.yyy or xxx->yyy 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 xxx.template yyy or xxx->template yyy.
- If the code contains the contruction xxx::yyy 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 construction, leading to
typename xxx::yyy.
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
void iterateOverSparseMatrix(const SparseMatrix& mat;
{
for (int k=0; k::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
*/
}