You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							136 lines
						
					
					
						
							6.1 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							136 lines
						
					
					
						
							6.1 KiB
						
					
					
				
								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.
							 | 
						|
								
							 | 
						|
								<b>Table of contents</b>
							 | 
						|
								  - \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 <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.triangularPart</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.triangularPart</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.triangularPart</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
							 | 
						|
								triangularPart</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 contructions <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 contruction <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 construction, 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
							 | 
						|
								
							 | 
						|
								*/
							 | 
						|
								}
							 |