我有一个2D矢量,我需要删除不包含足够值的块:
typedef vector<double> iniMatrix;
bool hasInsufficientEnergy() {
return true;
}
vector<double> Audio::filter(vector<iniMatrix>&blocks, double sumThres, double ZeroThres)
{
vector<double> totalEnergy;
vector<double> totalZeroCross;
double totalSum = sumThres * blocks.size();
double totalZero = ZeroThres * blocks.size();
vector<iniMatrix> blockked;
for(unsigned i=0; (i < blocks.size()); i++)
{
totalEnergy.push_back(abs(this->energy(blocks[i])));
totalZeroCross.push_back(zerocross(blocks[i]));
if(!totalEnergy[i] > totalSum || totalZeroCross[i] < ZeroThres)
{
hasInsufficientEnergy();
}else{
//hasInsufficientEnergy();
}
iniMatrix::iterator erase_after = remove_if(blocks[i].begin(), blocks[i].end(),
&hasInsufficientEnergy);
}
}
问题是erase_after并出现错误消息:
In function ‘_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator,
_OutputIterator, _Predicate) [with _InputIterator = __gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >, _OutputIterator =
__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >,
_Predicate = bool]’:
/usr/include/c++/4.2.1/bits/stl_algo.h:1302: instantiated from ‘_ForwardIterator
std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator =
__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >,
_Predicate = bool]’
Audio.cpp:105: instantiated from here
/usr/include/c++/4.2.1/bits/stl_algo.h:1227: error: ‘__pred’ cannot be used as a function
任何人对我出错的地方都有任何想法吗?
答案 0 :(得分:3)
std::remove_if
的第三个参数是一个谓词函数(或任何可调用的实体),它接受一个元素,如果需要删除true
则返回false
如果不。向量的向量元素(或“2D向量”,就像你所说的那样)是一个向量,在你的情况下是vector<double>
。这就是你的谓词的论点应该是:
bool HasInsufficientEnergy(const vector<double>& elem)
{
// herein is the code that tests elem and decides
// whether it should be removed or not
}
然后,您的filter()
方法不应包含多于此内容
void Audio::filter(vector<iniMatrix>&blocks)
{
auto it = std::remove_if(blocks.begin(), blocks.end(), &HasInsufficientEnergy);
blocks.erase(it, blocks.end());
}
如果你的谓词需要aditional参数,那么将它实现为一个将它们作为构造函数参数的类。你也需要重载operator()
,所以你有一个可调用的函子。
如果你的编译器支持C ++ 11,那么学习如何使用lambda函数,因为它们对于这个任务非常有用。
答案 1 :(得分:1)
remove_if
和类似的算法,期望一个函数,而不是一个值,即你应该传递一个函数指针或函数double const &
并返回bool
bool hasInsufficientEnergy(double const & element) {
// return true if it should be removed, false otherwise
}
然后
iniMatrix::iterator erase_after = remove_if(blocks[i].begin(), blocks[i].end(),
&hasInsufficientEnergy);
将起作用
答案 2 :(得分:1)
true
或false
不是函数对象。如果你想使用remove_if
,你必须给它一个指向函数或函数对象的指针,它将集合的成员作为参数并返回是否删除它。请查看std::remove_if
AFAICS,您可以将remove_if/erase
替换为if
并将其简化为:
for(auto i=blocks.begin(); i != blocks.end(); )
{
totalEnergy.push_back(abs(this->energy(*i)));
totalZeroCross.push_back(zerocross(*i));
if(!totalEnergy.rbegin() > totalSum || totalZeroCross.rbegin() < ZeroThres)
{
i = blocks.erase(i);
} else {
++i;
}
}