Note that there are some explanatory texts on larger screens.

plurals
  1. POWhether to choose an overload of template function or a partial specialization of a functor(function object)
    primarykey
    data
    text
    <p>The following is an excerpt of STL implementation of g++ (the sgi version of STL). I want to know why they use partial specialization instead of function overload.</p> <pre><code>template &lt;class InputIterator, class OutputIterator&gt; struct __copy_dispatch { OutputIterator operator()(InputIterator first, InputIterator last, OutputIterator result) { return __copy(first, last, result, iterator_category(first)); } }; //If the inputiterator and the outputiterator is all type T //This is a partial specialization of the generalized version template &lt;class T&gt; struct __copy_dispatch&lt;T*, T*&gt;//-----------------------(1) { T* operator()(T* first, T* last, T* result) { typedef typename __type_traits&lt;T&gt;::has_trivial_assignment_operator t; return __copy_t(first, last, result, t()); } }; //Strictly speaking this is a partial specialization of the last template function template &lt;class T&gt; struct __copy_dispatch&lt;const T*, T*&gt;//-----------------(2) { T* operator()(const T* first, const T* last, T* result) { typedef typename __type_traits&lt;T&gt;::has_trivial_assignment_operator t; return __copy_t(first, last, result, t()); } }; //The generalized version of copy template &lt;class InputIterator, class OutputIterator&gt; inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) { return __copy_dispatch&lt;InputIterator,OutputIterator&gt;()(first, last, result); } //A overload version inline char* copy(const char* first, const char* last, char* result) { memmove(result, first, last - first); return result + (last - first); } </code></pre> <p>What if I use an overload version like:</p> <pre><code>#include &lt;iostream&gt; using namespace std; template &lt;class InputIterator, class OutputIterator&gt; OutputIterator copy_dispatch(InputIterator first, InputIterator last, OutputIterator result) { cout &lt;&lt; "now in first" &lt;&lt; endl; return result; } template &lt;class T&gt; T* copy_dispatch(T* first, T* last, T* result) { cout &lt;&lt; "now in second" &lt;&lt; endl; return 0; } template &lt;class T&gt; T* copy_dispatch(const T* first, const T* last, T* result) { cout &lt;&lt; "now in third" &lt;&lt; endl; return 0; } int main( void ) { int a[]={1,2,3,4,5,6}; double b[] = {1.0,2.0,3.0,4.0,5.0,6.0}; int c[]={0,0,0,0,0,0}; int const d[]={0,0,0,0,0,0}; copy_dispatch(a,a+6, b); copy_dispatch(a, a+6, c); copy_dispatch(d, d+6, c); } </code></pre> <p>The output is:</p> <pre><code>now in first now in second now in third </code></pre> <p>Seems that it also works fine? </p> <p><strong>So is there any further reason to use a functor class with partial specialization instead of function overload</strong></p> <p><strong>UPDATES</strong></p> <p>Here are some other excerpts from sgi implementation of STL:</p> <pre><code>//sgi 4.5 template&lt;bool&gt; struct _Destroy_aux { template&lt;typename _ForwardIterator&gt; static void __destroy(_ForwardIterator __first, _ForwardIterator __last) { for (; __first != __last; ++__first) std::_Destroy(&amp;*__first); } };   template&lt;&gt; struct _Destroy_aux&lt;true&gt; { template&lt;typename _ForwardIterator&gt; static void __destroy(_ForwardIterator, _ForwardIterator) { }   }; //in an old version of sgi 2.9 this is implemented with function overload template &lt;class ForwardIterator&gt; inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) { for ( ; first &lt; last; ++first) destroy(&amp;*first); }   template &lt;class ForwardIterator&gt; inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {}   template &lt;class ForwardIterator, class T&gt; inline void __destroy(ForwardIterator first, ForwardIterator last, T*) { typedef typename __type_traits&lt;T&gt;::has_trivial_destructor trivial_destructor; __destroy_aux(first, last, trivial_destructor()); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload