<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>P1392R0: Differences Between Functions and Function Templates</title>
</head>

<body>
ISO/IEC JTC1 SC22 WG21 P1392R0<br/>
Davis Herring &lt;herring@lanl.gov&gt;<br/>
Roger Orr &lt;rogero@howzatt.demon.co.uk&gt;<br/>
Target audience: All of WG21<br/>
2019-01-14<br/>

<h1 align="center">Differences Between Functions and Function Templates</h1>

<h2>Abstract</h2>

There are a number of differences between functions and function templates in C++. This was highlighted during the discussion around 
inclusion of abbreviated function template syntax from the Concepts TS in the C++ WP.
<br>
This informal list of the main ways in which functions and function templates differ was assembled for that discussion,
so it is now published as a paper for use in a more general context.

<h2>Contents</h2>
<ol>
<li><a href="#differences">List of Differences</a>
  <ul>
  <li><a href="#forwarding">Forwarding/rvalue references</a>
  <li><a href="#definition_visibility">Definition visible at point of use</a>
  <li><a href="#odr">The One Definition Rule</a>
  <li><a href="#static_locals">Static Locals</a>
  <li><a href="#function_addresses">Function addresses</a>
  <li><a href="#local_types">Local types are distinct</a>
  <li><a href="#argument_deduction">Template argument deduction</a>
  <li><a href="#overload_resolution">Overload resolution</a>
  <li><a href="#selection">Selection via <code>f&lt;&gt;(/*...*/)</code></a>
  <li><a href="#specialization">Specialization</a>
  <li><a href="#special_members">Special members</a>
  <li><a href="#delayed_checking">Deferred checking</a>
  <li><a href="#default_arguments">Delayed checking of default arguments</a>
  <li><a href="#dependent_name">Dependent names</a>
  <li><a href="#specialize_or_overload">Specialize or Overload</a>
  </ul>
<li><a href="#history">Revision History</a>
<li><a href="#acknowledgements">Acknowledgements</a>
</ol>

<hr>
<h2><a name="differences">List of Differences</a></h2>

Here is a list of differences: there is no particular significance to their order.

<h3><a name="forwarding">Forwarding/rvalue references</a></h3>

A declaration of a function argument with type <code>T&amp;&amp;</code> is an rvalue reference.
<br>
A declaration of a function template argument with type <code>T&amp;&amp;</code> for some template argument <code>T</code> is a <i>forwarding</i> reference.

<p>
[<i>Example:</i> <pre>
struct T{};

void foo(T&amp;&amp; t); // rvalue reference

template &lt;typename T&gt;
void bar(T&amp;&amp; t); // forwarding reference

int main()
{
   T t{};
   foo(t); // error: cannot bind rvalue ref to t
   bar(t); // OK: reference collapse to T&amp;
}
</pre> -- <i>end example</i>]

<h3><a name="definition_visibility">Definition visible at point of use</a></h3>

A function and function template can be declared but not defined in a header.
At link time a definition of the entity must be provided.
<p>
For a function this simply involves providing a definition in one of the TUs.
<p>
This is in general infeasible for a function template as a specialization or explicit instantiation must be provided for <b>every</b> instantiation that might be invoked.
<p>
(Additionally, such explicit specializations must be <i>declared</i> in every translation unit, although absence may not be diagnosed by all implementations.)
<p>
This can be a problem as code changes: you might for example start with a function in an anonymous namespace, used in
a single .cpp file.<br>
Then you want to use it elsewhere, so you move the definition into a public namespace, and put
the declaration in a header so you can use it in a second .cpp file.

<h3><a name="odr">The One Definition Rule</a></h3>

A function definition can only be provided <b>once</b> in a given program (unless the function is marked <code>inline</code>).
<p>
A function template can be defined in <i>multiple</i> translation units, and the linker will pick one copy of each actual instantiation.

<h3><a name="static_locals">Static Locals</a></h3>

In a function there is a single instance of a function-scope static; for a function template there is one instance per instantiation.

<p>
[<i>Example:</i> <pre>
inline void foo()
{
   static object theObject; // only one instance
}

template &lt;typename T&gt;
void foo()
{
   static object theObjects; // one instance <i>per T</i>
}
</pre> -- <i>end example</i>]

<h3><a name="function_addresses">Function addresses</a></h3>

There a single address for a function, for a function template there is potentially a separate address for each instantiation.
<p>
A (non-inlined) function has a single instantiation in a program; multiple instantiations of a (non-inlined) function template increase the code size.

<h3><a name="local_types">Local types are distinct</a></h3>

If a local type is defined within a function template each instantiation of the function template produces a <i>distinct</i> type.
<p>
[<i>Example:</i> <pre>
template&lt;class T&gt;
auto f(const T&amp;) {
  struct A {};
  return A{};
}

void g(short s) {
  auto a=f(s);
  a=f(s+1);      // error -- type mismatch
}
</pre> -- <i>end example</i>]

<h3><a name="argument_deduction">Template argument deduction</a></h3>

<h3>vs. implicit conversion sequences</h3>

Deduction of function template arguments does not consider implicit conversion sequences.

<p>
[<i>Example:</i> <pre>
struct X{};
struct Y : X {};

void foo(X, X);

template&lt;typename T&gt;
void bar(T, T);

int main()
{
  X x;
  Y y;
  foo(x, y); // OK
  bar(x, y); // error
}
</pre> -- <i>end example</i>]
<p>
or a different case:
<p>
[<i>Example:</i> <pre>
struct X{X(int) {} };

bool operator==(X, X);

bool zero(X x) {return x == 0;}  // OK

template&lt;typename T&gt;
struct Y { Y(T) {} };

template&lt;class T&gt;
bool operator==(Y&lt;T&gt;, Y&lt;T&gt;);  // non-member allows conversions, right?

bool zero(Y&lt;int&gt; y) {return y == 0;}  // error: deduction failed

</pre> -- <i>end example</i>]

<h3>Initializer lists</h3>

Templates do not allow deduction of <code>initializer_list</code>.

<p>
[<i>Example:</i> <pre>
#include &lt;initializer_list&gt;

void f(std::initializer_list&lt;int&gt; i) {}

template &lt;typename T&gt;
void ft(T t) {}

int main()
{   
    f({1, 3, 5});

    ft({1, 3, 5}); // error: can't deduce initializer_list
}
</pre> -- <i>end example</i>]

<h3>Contextual cases</h3>

<h4>Conversion functions</h4>

Deduction is required to use a conversion function template.

[<i>Example:</i> <pre>
auto f() {
  auto x = [](int){};
  auto y = [](auto){};

  auto z = +y;   // error: no conversion found
  return +x;   // OK
}
</pre> -- <i>end example</i>]

<h4>Pointers to overload sets</h4>

Taking the address of a function returns a unique value.<br>
Taking the address of a function template does not return a single value.
<p>
This makes using function pointers with function templates trickier than with functions as the instantiation required must be explicitly specified.
<p>
This can be done by giving the desired template arguments for the specialization desired.
<p>
When the template arguments are <i>deducable</i> an alternative is using a pointer to a function with the desired argument types to select the correct instantiation.

<p>
[<i>Example:</i> <pre>
struct X {};

void foo(X, X);
X make_foo();

template&lt;typename T&gt;
void bar(T, T);

template&lt;typename T&gt;
T make_bar(T, T);

int main()
{
  auto foo_ptr = &amp;foo; // OK
  auto make_foo_ptr = &amp;make_foo; // OK

  auto bar_ptr = &amp;bar; // error
  auto make_bar_ptr = &amp;make_bar; // error

  auto bar_ptr1 = &amp;bar&lt;X&gt;; // OK
  auto make_bar_ptr1 = &amp;make_bar&lt;X&gt;; // OK

  void (*bar_ptr2)(X, X) = &amp;bar; // OK, template arguments deduced
}
</pre> -- <i>end example</i>]

<h3>Function templates as arguments</h3>

There are differences between using functions and using function templates as arguments to function templates.

<p>
[<i>Example:</i> <pre>
#include &lt;iostream&gt;

template&lt;class T&gt;
T f_template(const T &amp;arg){
  return arg;
}
int f_int(const int &amp;arg){
  return arg;
}
auto f_lambda = [](const int &amp;arg){
  return arg;
};

auto f_glambda = [](const auto &amp;arg){
  return arg;
}

template&lt;class F, class T&gt;
auto call_me(F f, const T&amp;arg){
  return f(arg);
}

int main(int, char**){
  std::cout &lt;&lt; call_me(f_int, 42) &lt;&lt; "\n";        // works
  std::cout &lt;&lt; call_me(f_lambda, 42) &lt;&lt; "\n";     // works
  std::cout &lt;&lt; call_me(f_glambda, 42) &lt;&lt; "\n";    // generic lambda works
  std::cout &lt;&lt; call_me(f_template, 42) &lt;&lt; "\n";   // template doesn't work
}
</pre> -- <i>end example</i>]

<h4>Operator delete template</h4>

An operator delete template behaves differently from a non-template.
<p>
[<i>Example:</i> <pre>
struct A {
  A() {throw 0;}
  void* operator new(std::size_t,int,short);
  template&lt;class T&gt;
  void operator delete(void*,T,T);
};

void f() {new (0,0) A;} // no deallocation function called
</pre> -- <i>end example</i>]

<h3><a name="overload_resolution">Overload resolution</a></h3>

<h3>SFINAE</h3>

Function templates whose declarations cannot be substituted into are simply removed from the overload set.<br>
Functions are either present or not present and there are no techniques to remove them from consideration for particular types of argument.

<h3>Best viable function</h3>

The rules for determining the best viable function for overloaded functions and function templates are different.

<p>
[<i>Example:</i> <pre>
template&lt;class T&gt;
void f(T*);         // #1
template&lt;class T&gt;
void f(T**);        // #2

void g(int*);       // g ~ f&lt;int&gt;
void g(int**);      // and yet...

void h() {
  f&lt;int&gt;(nullptr);  // OK: calls #2
  g(nullptr);       // error: ambiguous
}
</pre> -- <i>end example</i>]

<h3>Tie-breaking</h3>

In the case of a tie-break between a function and a function template the function wins.

<h3>Explicit specializations</h3>

The interaction between overloading (based on the primary template) and explicit specializations can be confusing.
<p>
[<i>Example:</i> <pre>
template&lt;class T&gt;
void f(const T&amp;);               // #1
template&lt;&gt; void f(const int&amp;);  // #2: specializes #1

void f(volatile int&amp;);          // #3

void g(int i) {f(i);}           // calls #3
</pre> -- <i>end example</i>]
<p>
If we added one (more) template parameter to each of the three declarations of f, the call would become ambiguous.
 
<h3><a name="selection">Selection via <code>f&lt;&gt;(/*...*/)</code></a></h3>

For a function template you can select the template explicitly by providing an empty template argument list.

<p>
[<i>Example:</i> <pre>
void foo(int);

template&lt;typename T&gt;
void foo(T);

int main()
{
  foo(1); // Selects function (best match)
  foo&lt;&gt;(1); // Selects function template
}
</pre> -- <i>end example</i>]

<h3><a name="specialization">Specialization</a></h3>

For a function template you can provide explicit specializations (you obviously cannot for a non-template.)

<p>
[<i>Example:</i> <pre>
template&lt;typename T&gt;
void bar(T);

template&lt;&gt;
void bar(double) {}

int main()
{
  bar(1.0);
}
</pre> -- <i>end example</i>]
<p>
For a function template you can specify an instantation explicitly by providing the template arguments.

<p>
[<i>Example:</i> <pre>
template&lt;typename T&gt;
void bar(T);

int main()
{
  bar&lt;int&gt;(1.0);
}
</pre> -- <i>end example</i>]

<h3><a name="special_members">Special members</a></h3>

A function template cannot be a special member function, even if some specialization of it meets the requirements.
<p>
[<i>Example:</i> (from [class.copy.ctor] p5) <pre>
struct S {
  template&lt;typename T&gt; S(T);
  S();
};

S g;

void h() {
  S a(g); // does not instantiate the member template to produce S::S&lt;S&gt;(S);
          // uses the implicitly declared copy constructor
}
</pre> -- <i>end example</i>]
<p>
<h3><a name="delayed_checking">Deferred checking</a></h3>

A function is compiled when the definition is reached.
<p>
A function template has two phases of compilation, once when the definition is reached and once when the function is instantiated.
<br>
This can mean there is no guarantee of validity checking until instantiation.
<p>
[<i>Example:</i> <pre>
template&lt;class T&gt;
bool equal(const Container&lt;T&gt; &amp;c,const T *a) {
  for(int i=0;i&lt;c.size();++i)
    if(c[i]!=a) return false;
  return true;
}
</pre> -- <i>end example</i>]
<p>
The expression <code>c[i]!=a</code> is comparing a <code>T</code> against a <code>T*</code> and will (almost certainly) fail at instantiation.
<br>
(And even it instantiates, it's unlikely to be the correct semantics!)
<h3>Deferred checking - static_assert</h3>

In a function a <code>static_assert</code> triggers at definition time.
<br>
In a function template a (dependent) <code>static_assert</code> triggers at instantation time.
<p>
[<i>Example:</i> <pre>
void foo(int i)
{
  static_assert(sizeof(i) == 88); // asserts: (typo for '8')
}

template&lt;typename T&gt;
void bar(T t)
{
  static_assert(sizeof(int) == 88); //  ill-formed, no diagnostic required (non-dependent)
  static_assert(sizeof(T) == 88); // asserts <b>when instantiated</b> (dependent)
}
</pre> -- <i>end example</i>]
<p>

<h3><a name="default_arguments">Delayed checking of default arguments</a></h3>

The handling of default arguments is different as they are checked at declaration time for functions, but at instantiation for function templates.

<p>
[<i>Example:</i> <pre>
struct X {};

void foo(X arg = 42); // error: even if default argument never used

template&lt;typename T&gt;
void bar(T arg = 42); // OK

int main()
{
  X x;
  bar(x); // OK
  bar&lt;X&gt;(); // error: only if default argument <i>used</i>
}
</pre> -- <i>end example</i>]

<h3><a name="dependent_name">Dependent names</a></h3>

<h4>Access to declarations after function (template) declaration</h4>

<p>
[<i>Example:</i> <pre>
// Taken from [temp.res] p10, slightly simplified

void f(char);
enum E { e };

template&lt;class T&gt; void g(T t) {
  f(1); // f(char)
  f(t); // dependent
}

void f(E);

void h() {
  g(e); // will cause one call of f(char) followed by one call of f(E)
}
</pre> -- <i>end example</i>]
<p>
The equivalent case for a function has <i>different</i> behaviour:

<p>
[<i>Example:</i> <pre>
void f(char);
enum E { e };

void g(E t) {
  f(1); // f(char)
  f(t); // f(char) !
}

void f(E);

void h() {
  g(e); // will cause <b>two</b> calls of f(char)
}
</pre> -- <i>end example</i>]

<h4>Necessity of <code>typename</code> and <code>template</code></h4>

When accessing dependent names additional syntax is required in certain cases.
<p>
Note that while <a href="http://wg21.link/p0634r3">P0634R3</a> (applied to the working paper in JAX '18) <i>reduces</i> the number of places where <code>typename</code> is required, it does not eliminate them all.
<br>
For example, that paper gives an example where omitting <code>typename</code> changes the meaning of the code:
<pre>
template&lt;typename T&gt; void f() {
  void (*pf)(T::X); // Variable pf of type void* initialized with T::X
};
</pre>
If <code>typename</code> is added:
<pre>
template&lt;typename T&gt; void f() {
  void (*pf)(typename T::X); // Variable pf of type pointer to function taking T::X and returning void.
};
</pre>

<p>
There are also cases where <code>template</code> must be used to avoid parsing ambiguity with the less than operator.
<p>
[<i>Example:</i> <pre>
// Taken from [temp.names] p3, slightly simplified

struct X {
  template&lt;std::size_t&gt; X* alloc();
  template&lt;std::size_t&gt; static X* adjust();
};

template&lt;class T&gt; void f(T* p) {
  T* p1 = p-&gt;alloc&lt;200&gt;(); // ill-formed: &lt; means less than
  T* p2 = p-&gt;template alloc&lt;200&gt;(); // OK: &lt; starts template argument list
}
</pre> -- <i>end example</i>]
<p>

<h3><a name="specialize_or_overload">Specialize or Overload</a></h3>

Whether to specialize or overload depends on whether the first declaration is a function or a function template.
<p>
With the "Constrained auto" syntax adopted in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html">P1141</a>:
<p>
[<i>Example:</i> </p><pre>
   // library code
   template&lt;class T&gt;
   concept Container=/*...*/;

   struct Widget {};
   struct Button : Widget {};

   // user code
   void f(Container auto&amp;) {}
   template&lt;&gt; void f(std::vector&lt;int&gt;&amp;) {} // OK

   void g(Widget&amp;) {}
   template&lt;&gt; void g(Button&amp;) {} // error
</pre> -- <i>end example</i>]
<p>
With the abbreviated syntax from the Concepts TS the difference between <code>f</code> and <code>g</code> becomes less visible:
<p>
[<i>Example:</i> </p><pre>
   // user code
   void f(Container&amp;) {}
   template&lt;&gt; void f(std::vector&lt;int&gt;&amp;) {} // OK

   void g(Widget&amp;) {}
   template&lt;&gt; void g(Button&amp;) {} // error
</pre> -- <i>end example</i>]

<hr>
<h3><a name="history">Revision history</a></h3>

<ul>
  <li>P1392R0 (this document): "Specialize or Overload" revised following adoption of P1141 into the C++ Working Paper.<br>
  Removal of "multiple overloads with satisfied constraints" as this is specific to the Concepts TS merging discussion.<br>
  Other additional minor edits.</li>
  <li>Pre-publication: A first, informal, version of this paper was produced in Jun 2018 for use during discussion in Rapperswil and attached to the EWG Wiki.</li>
</ul>
<hr>
<p>
<h3><a name="acknowledgements">Acknowledgements</a></h3>
Thanks to those who gave additional suggestions and examples, including:
<ul>
<li>Richard Smith
<li>Hubert Matthews
<li>Sam Finch
<li>Thomas Russell
</ul>
Any <i>errors</i> in this paper are the responsiblity of the paper authors.
</body>
</html>