我假设一个位掩码存储在一个容器中(以支持系统上超过sizeof(uintmax_t) 位的位掩码)。在这种情况下,解决方案的本质是:
std::remove_copy_if(v.begin(), v.end(), std::back_inserter(out),
!*boost::lambda::var(pred)++);
其中v - 输入向量; out - 存储结果的向量; pred - 位掩码上的迭代器。
如果您想避开boost::lambda,那么很容易模拟:
template <class InputIterator, class OutputIterator, class PredicateIterator>
void copy_if(InputIterator first, InputIterator last, OutputIterator result,
PredicateIterator pred) {
for ( ; first != last; ++first)
if (*pred++)
*result++ = *first;
}
可以按如下方式使用(使用与上例相同的符号):
copy_if(v.begin(), v.end(), std::back_inserter(out), pred);
或同样使用谓词:
template <class Iterator>
class Pred {
Iterator it;
public:
Pred(Iterator it_) : it(it_) {}
template <class T>
bool operator ()(T /* ignore argument */) { return !*it++; }
};
template <class Iterator>
Pred<Iterator> iterator2predicate(Iterator it) {
return Pred<Iterator>(it);
}
可以这样使用:
std::remove_copy_if(v.begin(), v.end(), std::back_inserter(out),
iterator2predicate(pred));
示例(使用boost::lambda,但很容易被上面两个其他选项替换):
/** g++ -Wall -Ipath/to/boost -o filter_array filter_array.cpp */
#include <algorithm>
#include <iostream>
#include <iterator> // back_inserter()
#include <vector>
#include <boost/lambda/lambda.hpp>
#define LEN(array) (sizeof(array) / sizeof(*(array)))
#define P(v) { std::for_each(v.begin(), v.end(), \
std::cout << boost::lambda::_1 << " "); \
std::cout << std::endl; }
int main() {
int a[] = {123, 345, 678, 890, 555,};
const size_t n = LEN(a);
bool bits[][n] = {
1, 0, 1, 0, 0,
0, 0, 1, 1, 0,
0, 0, 0, 0, 1,
};
typedef std::vector<int> Array;
Array v(a, a + n);
P(v);
for (size_t i = 0; i < LEN(bits); ++i) {
Array out;
std::vector<bool> b(bits[i], bits[i] + LEN(bits[i]));
std::vector<bool>::const_iterator pred = b.begin();
P(b);
std::remove_copy_if(v.begin(), v.end(), std::back_inserter(out),
!*boost::lambda::var(pred)++);
P(out);
}
}
输出:
123 345 678 890 555
1 0 1 0 0
123 678
0 0 1 1 0
678 890
0 0 0 0 1
555