Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to implement copy_if in terms of std::remove_copy_if?
    primarykey
    data
    text
    <p>I have worked out a solution that works most of the time:</p> <pre><code>#include &lt;algorithm&gt; #include &lt;functional&gt; #include &lt;iostream&gt; #include &lt;vector&gt; // Overload that takes a function pointer template&lt;class ForwardIterator, class OutputIterator, class ArgType&gt; void copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, bool (*inPredicate)(ArgType)) { typedef std::pointer_to_unary_function&lt;ArgType, bool&gt; Adapter; std::remove_copy_if(begin, end, out, std::unary_negate&lt;Adapter&gt;(Adapter(inPredicate))); } // Overload that takes a function object template&lt;class ForwardIterator, class OutputIterator, class Functor&gt; void copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, Functor inFunctor) { std::remove_copy_if(begin, end, out, std::unary_negate&lt;Functor&gt;(inFunctor)); } bool is_odd(int inValue) { return inValue % 2 == 1; } bool is_odd_const_ref(const int &amp; inValue) { return inValue % 2 == 1; } struct is_odd_functor : public std::unary_function&lt;int, bool&gt; { bool operator() (const int &amp; inValue) const { return inValue % 2 == 1; } }; int main() { std::vector&lt;int&gt; numbers; numbers.push_back(0); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); std::vector&lt;int&gt; copy; // Functor: Ok copy_if(numbers.begin(), numbers.end(), std::back_inserter(copy), is_odd_functor()); // Function pointer: Ok copy_if(numbers.begin(), numbers.end(), std::back_inserter(copy), is_odd); // Function pointer that takes const ref: Compiler error copy_if(numbers.begin(), numbers.end(), std::back_inserter(copy), is_odd_const_ref); return 0; } </code></pre> <p>The only situation where it doesn't work is when the function pointer takes a const ref argument. This results in the following compiler error:</p> <pre><code>/usr/include/c++/4.2.1/bits/stl_function.h: In instantiation of ‘std::unary_negate&lt;std::pointer_to_unary_function&lt;const int&amp;, bool&gt; &gt;’: main.cpp:11: instantiated from ‘void copy_if(ForwardIterator, ForwardIterator, OutputIterator, bool (*)(ArgType)) [with ForwardIterator = __gnu_cxx::__normal_iterator&lt;int*, std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, OutputIterator = std::back_insert_iterator&lt;std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, ArgType = const int&amp;]’ main.cpp:53: instantiated from here /usr/include/c++/4.2.1/bits/stl_function.h:322: error: forming reference to reference type ‘const int&amp;’ /usr/include/c++/4.2.1/bits/stl_algo.h: In function ‘_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator, _OutputIterator, _Predicate) [with _InputIterator = __gnu_cxx::__normal_iterator&lt;int*, std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, _OutputIterator = std::back_insert_iterator&lt;std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, _Predicate = std::unary_negate&lt;std::pointer_to_unary_function&lt;const int&amp;, bool&gt; &gt;]’: main.cpp:11: instantiated from ‘void copy_if(ForwardIterator, ForwardIterator, OutputIterator, bool (*)(ArgType)) [with ForwardIterator = __gnu_cxx::__normal_iterator&lt;int*, std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, OutputIterator = std::back_insert_iterator&lt;std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, ArgType = const int&amp;]’ main.cpp:53: instantiated from here /usr/include/c++/4.2.1/bits/stl_algo.h:1227: error: no match for call to ‘(std::unary_negate&lt;std::pointer_to_unary_function&lt;const int&amp;, bool&gt; &gt;) (int&amp;)’ </code></pre> <p>Apparently a reference to a reference is attempted to be made here.</p> <p>My question is: How can I implement a <code>copy_if</code> that meets the following conditions:</p> <ol> <li>implementation in terms of std::remove_copy_if</li> <li>must work with function objects and function pointers</li> <li>without defining helper classes (outside the function scope)</li> <li>using pure C++ and STL (no C++0x or boost)</li> </ol> <h3>Update</h3> <p>I assume that this is possible because it works with <code>boost::bind</code> :</p> <pre><code>template&lt;class ForwardIterator, class OutputIterator, class Functor&gt; void copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, Functor inFunctor) { std::remove_copy_if(begin, end, out, !boost::bind(inFunctor, _1)); } </code></pre>
    singulars
    1. This table or related slice is empty.
    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.
 

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