- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我已经制定了一个大部分时间都有效的解决方案:
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
// Overload that takes a function pointer
template<class ForwardIterator, class OutputIterator, class ArgType>
void copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, bool (*inPredicate)(ArgType))
{
typedef std::pointer_to_unary_function<ArgType, bool> Adapter;
std::remove_copy_if(begin, end, out, std::unary_negate<Adapter>(Adapter(inPredicate)));
}
// Overload that takes a function object
template<class ForwardIterator, class OutputIterator, class Functor>
void copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, Functor inFunctor)
{
std::remove_copy_if(begin, end, out, std::unary_negate<Functor>(inFunctor));
}
bool is_odd(int inValue)
{
return inValue % 2 == 1;
}
bool is_odd_const_ref(const int & inValue)
{
return inValue % 2 == 1;
}
struct is_odd_functor : public std::unary_function<int, bool>
{
bool operator() (const int & inValue) const { return inValue % 2 == 1; }
};
int main()
{
std::vector<int> numbers;
numbers.push_back(0);
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
std::vector<int> 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;
}
唯一不起作用的情况是函数指针采用 const ref 参数。这会导致以下编译器错误:
/usr/include/c++/4.2.1/bits/stl_function.h: In instantiation of ‘std::unary_negate<std::pointer_to_unary_function<const int&, bool> >’:
main.cpp:11: instantiated from ‘void copy_if(ForwardIterator, ForwardIterator, OutputIterator, bool (*)(ArgType)) [with ForwardIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, OutputIterator = std::back_insert_iterator<std::vector<int, std::allocator<int> > >, ArgType = const int&]’
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&’
/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<int*, std::vector<int, std::allocator<int> > >, _OutputIterator = std::back_insert_iterator<std::vector<int, std::allocator<int> > >, _Predicate = std::unary_negate<std::pointer_to_unary_function<const int&, bool> >]’:
main.cpp:11: instantiated from ‘void copy_if(ForwardIterator, ForwardIterator, OutputIterator, bool (*)(ArgType)) [with ForwardIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, OutputIterator = std::back_insert_iterator<std::vector<int, std::allocator<int> > >, ArgType = const int&]’
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<std::pointer_to_unary_function<const int&, bool> >) (int&)’
显然这里试图引用一个引用。
我的问题是:如何实现满足以下条件的copy_if
:
我认为这是可能的,因为它适用于 boost::bind
:
template<class ForwardIterator, class OutputIterator, class Functor>
void copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, Functor inFunctor)
{
std::remove_copy_if(begin, end, out, !boost::bind(inFunctor, _1));
}
最佳答案
C++03 不常见 <functional>
,您的工作量太多了。消除 Adapter
支持工厂功能。
// Overload that takes a function pointer
template<class ForwardIterator, class OutputIterator, class ArgType>
OutputIterator copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, bool (*inPredicate)(ArgType))
{
return std::remove_copy_if(begin, end, out, std::not1(std::ptr_fun(inPredicate)));
}
// Overload that takes a function object
template<class ForwardIterator, class OutputIterator, class Functor>
OutputIterator copy_if(ForwardIterator begin, ForwardIterator end, OutputIterator out, Functor inPredicate)
{
return std::remove_copy_if(begin, end, out, std::not1(inPredicate));
}
另外,我要指出,TR1 应该添加到您决定不使用的现在常用设施的列表中。
此外,如果函数指针 copy_if
会更优雅一些重载称为仿函数一个,而不是两者都是完整的实现。
另外,正如@wilhelm 指出的那样,返回类型应该是 OutputIterator
.我已在此代码段中修复它。
关于c++ - 如何根据 std::remove_copy_if 实现 copy_if?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5825532/
根据http://www.cplusplus.com中的代码 template OutputIterator remove_copy_if (InputIterator first, Input
我正在尝试使用 vector 将 back_insert_iterator 与 remove_copy_if 结合使用,但我遇到了编译错误。 你知道下面的代码为什么不对吗? #include #in
能否请您向我解释一下我在以下代码中做错了什么?我希望第二个 vector 中的值 >= 80 但它是空的。 #include #include #include using namespace
这可能是 STL 中命名最差的函数吗? (反问) std::remove_copy_if() 实际上似乎没有进行任何删除。据我所知,它的行为更像是 copy_if_not。 否定有点令人困惑,但可以使
我试图找到 copy(copy_if) 和 remove_copy(remove_copy_if) STL 算法之间的任何区别,但似乎没有任何实际区别: Source and destination
我已经制定了一个大部分时间都有效的解决方案: #include #include #include #include // Overload that takes a function poi
我试图将 std::ispunct 作为最后一个参数传递给 remove_copy_if,但发现编译失败。但是,如果我传递 ispunct(只是删除了 std::),程序会按预期编译和运行。 代码:
我是一名优秀的程序员,十分优秀!