Why does the std::copy_if signature not constrain the predicate type : <p>Imagine we have the following situation:    </p>

<pre><code>struct A
{
    int i;
};

struct B
{
    A a;
    int other_things;
};

bool predicate( const A&amp; a)
{
    return a.i &gt; 123;
}

bool predicate( const B&amp; b)
{
    return predicate(b.a);
}

int main()
{
    std::vector&lt; A &gt; a_source;
    std::vector&lt; B &gt; b_source;

    std::vector&lt; A &gt; a_target;
    std::vector&lt; B &gt; b_target;

    std::copy_if(a_source.begin(), a_source.end(), std::back_inserter( a_target ), predicate);
    std::copy_if(b_source.begin(), b_source.end(), std::back_inserter( b_target ), predicate);

    return 0;
}
</code></pre>

<p>Both the call to <code>std::copy_if</code> generate a compile error, because the correct overload of <code>predicate()</code> function cannot be infered by the compiler since the <code>std::copy_if</code> template signature accepts any type of predicate:</p>

<pre><code>template&lt;typename _IIter, 
         typename _OIter, 
         typename _Predicate&gt;
_OIter copy_if( // etc...
</code></pre>

<p>I found the overload resolution working if I wrap the <code>std::copy_if</code> call into a more constrained template function:</p>

<pre><code>template&lt;typename _IIter, 
         typename _OIter, 
         typename _Predicate = bool( const typename std::iterator_traits&lt;_IIter&gt;::value_type&amp; ) &gt;
void copy_if( _IIter source_begin, 
              _IIter source_end, 
              _OIter target,  
              _Predicate pred)
{
    std::copy_if( source_begin, source_end, target, pred );
} 
</code></pre>

<p>My question is: why in the STL is it not already constrained like this? From what I've seen, if the <code>_Predicate</code> type is not a function that returns <code>bool</code> and accepts the iterated input type, it is going to generate a compiler error anyway. So why not putting this constrain already in the signature, so that overload resolution can work?</p>
