Channels ▼
RSS

Using Template Functions to Customize Library Behavior


March 2001/Using Template Functions to Customize Library Behavior/Sidebar

Understanding Function Template Selection


In C++, a more specialized version of a class template is called a partial specialization. While the syntax for specialized function templates is the same as for partial specializations, the behavior can be somewhat different. Hence, the term "partial specialization" is not used with regard to functions. While class templates are partially specialized, functions are simply overloaded. The function template overload a compiler chooses in response to a particular call depends on the concept of which one is "more specialized" than the others. The process is similar to selecting one candidate over the other if and only if the set of all functions possibly generated from the selectee is a proper subset of another.

For example, consider these two function templates:

template<class T>
void foo(T t);
 
template<class T>
void foo(std::vector<T> t);

Of these two, the second would be considered more specialized than the first. When considering the first function template, the compiler could generate a function with distinct types starting out like this:

void foo(int t);
void foo(float t);
void foo(std::string t);
...

For the second, the compiler could generate:

void foo(std::vector<int> t);
void foo(std::vector<float> t);
void foo(std::vector<std::string> t);
...

Both of these lists could go on forever; they are unbounded sets. In the first list, the parameter can be any distinct type, but in the second, the parameter must be the vector class specialized on a type. Any element in the second list could be used in the first, while the reverse is not true. This makes the second list a proper subset of the first.

Using function templates as described here is intuitive and useful. The subset discussion is a simplification, however, since the criterion for whether a function generated by one template function could be used by another is whether it is considered a match. A "match" means the function parameters arrived at by argument deduction are an exact match, with no implicit conversions. The process by which one function template is preferred over another is called partial ordering. Of course, there are additional rules and special cases for both partial ordering and argument deduction.

There are also areas where the writers of compilers, programs, and standards don’t always agree. It is a good idea to stay away from these areas. For example, consider these two function templates:

template<class T>
int foo(T t);

template<class T>
int foo(const T& t);

Given a call to these functions, such as the following:

MyClass mc;
foo(mc);

some compilers will report that the call foo(mc) is ambiguous. Others will compile just fine and pick the second function for execution.

Here is another example:

template<class T>
int foo(T*);

template<class T>
int foo(T&);

Given this call:

MyClass * mc = new MyClass();
foo(mc);

different compilers will report that foo(mc) is ambiguous, or compile but disagree with each other about which function actually gets called. Staying away from these fringe areas will make you a happier engineer. For a more precise description of the rules on how function templates are selected, see the C++ Standard under "Partial Ordering of Function Templates" (Chapter 14, Section 5.5.2) and "Template Argument Deduction" (Chapter 14, Section8.2).


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.