std::remove_if 中的谓词错误
Error with a predicate in std::remove_if
我基本上有一个 std::deque
个对象,我想根据对象的给定成员变量的条件删除其中一些对象,这样我就可以使用谓词,但是我有错误不是很懂
出于 STL 原因(共享指针),我将 g++
与 -std=c++11
一起使用,但我试图在 windows 上使用非 c++11
的 MVS 来解决这个问题代码,所以我正在寻找一个非 c++11
解决方案,没有 lamdas 等
密码是:
#include <iostream> // for std::cout and std::endl
#include <cstdio> // for getchar()
#include <memory> // for std::shared_ptr
#include <deque> // for std::deque
#include <algorithm> // for std::earse and std::remove_if
class A
{
private:
int _i;
double _d;
public:
A(int i, double d)
{
_i = i;
_d = d;
}
int geti()const
{
return _i;
}
double getValueOnWhichToCheck()const
{
return _d;
}
};
typedef std::shared_ptr<A> A_shared_ptr;
typedef std::deque<A_shared_ptr> list_type;
void PrintDeque(list_type & dq)
{
if (0 == dq.size())
{
std::cout << "Empty deque." << std::endl;
}
else
{
for (int i = 0 ; i < dq.size() ; ++i)
{
std::cout << i+1 << "\t" << dq[i] << std::endl;
}
}
}
class B
{
public:
double getThreshold() // Non constant for a reason as in real code it isn't
{
return 24.987; // comes from a calculation not needed here so I return a constant.
}
bool Predicate(A_shared_ptr & a)
{
return a->getValueOnWhichToCheck() >= getThreshold();
}
void DoStuff()
{
A_shared_ptr pT1 = std::make_shared<A>(A(2, -6.899987));
A_shared_ptr pT2 = std::make_shared<A>(A(876, 889.878762));
A_shared_ptr pT3 = std::make_shared<A>(A(-24, 48.98924));
A_shared_ptr pT4 = std::make_shared<A>(A(78, -6654.98980));
A_shared_ptr pT5 = std::make_shared<A>(A(6752, 3.141594209));
list_type dq = {pT1,pT2,pT3,pT4,pT5};
PrintDeque(dq);
bool (B::*PtrToPredicate)(A_shared_ptr &) = &B::Predicate;
dq.erase(std::remove_if(dq.begin(), dq.end(), PtrToPredicate),dq.end());
PrintDeque(dq);
}
};
int main()
{
B * pB = new B();
pB->DoStuff();
getchar();
}
g++ -std=c++11 main.cpp -o main
的输出是:
In file included from /usr/include/c++/5/bits/stl_algobase.h:71:0,
from /usr/include/c++/5/bits/char_traits.h:39,
from /usr/include/c++/5/ios:40,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from main.cpp:1:
/usr/include/c++/5/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with _Iterator = std::_Deque_iterator<std::shared_ptr<A>, std::shared_ptr<A>&, std::shared_ptr<A>*>; _Predicate = bool (B::*)(std::shared_ptr<A>&)]’:
/usr/include/c++/5/bits/stl_algo.h:866:20: required from ‘_ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = std::_Deque_iterator<std::shared_ptr<A>, std::shared_ptr<A>&, std::shared_ptr<A>*>; _Predicate = __gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>]’
/usr/include/c++/5/bits/stl_algo.h:936:30: required from ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = std::_Deque_iterator<std::shared_ptr<A>, std::shared_ptr<A>&, std::shared_ptr<A>*>; _Predicate = bool (B::*)(std::shared_ptr<A>&)]’
main.cpp:67:73: required from here
/usr/include/c++/5/bits/predefined_ops.h:234:30: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>*)this)->__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>::_M_pred (...)’, e.g. ‘(... ->* ((__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>*)this)->__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>::_M_pred) (...)’
{ return bool(_M_pred(*__it)); }
^
您将无法在 remove_if
中使用非静态成员函数指针。 remove_if
需要普通函数指针、静态成员函数指针或函数对象。它不能使用成员函数指针的原因是因为它需要 class 的实例才能调用该函数,而您不能将其包装到调用中
您要么需要创建 Predicate
static
,创建函数对象并传递其实例,要么在调用站点中使用 lambda。
不喜欢函数指针,但使用 lambda 的 this 似乎可以编译...https://ideone.com/0StRcw
dq.erase(std::remove_if(dq.begin(), dq.end(), [this](const std::shared_ptr<A>& a) {
return a->getValueOnWhichToCheck() >= getThreshold();
}),dq.end());
或者没有 lambdas..
auto predicateToUse = std::bind(&B::Predicate, this, std::placeholders::_1);
dq.erase(std::remove_if(dq.begin(), dq.end(), predicateToUse), dq.end());
不自动更新:
dq.erase(std::remove_if(dq.begin(), dq.end(), std::bind(&B::Predicate, this, std::placeholders::_1)), dq.end());
我基本上有一个 std::deque
个对象,我想根据对象的给定成员变量的条件删除其中一些对象,这样我就可以使用谓词,但是我有错误不是很懂
出于 STL 原因(共享指针),我将 g++
与 -std=c++11
一起使用,但我试图在 windows 上使用非 c++11
的 MVS 来解决这个问题代码,所以我正在寻找一个非 c++11
解决方案,没有 lamdas 等
密码是:
#include <iostream> // for std::cout and std::endl
#include <cstdio> // for getchar()
#include <memory> // for std::shared_ptr
#include <deque> // for std::deque
#include <algorithm> // for std::earse and std::remove_if
class A
{
private:
int _i;
double _d;
public:
A(int i, double d)
{
_i = i;
_d = d;
}
int geti()const
{
return _i;
}
double getValueOnWhichToCheck()const
{
return _d;
}
};
typedef std::shared_ptr<A> A_shared_ptr;
typedef std::deque<A_shared_ptr> list_type;
void PrintDeque(list_type & dq)
{
if (0 == dq.size())
{
std::cout << "Empty deque." << std::endl;
}
else
{
for (int i = 0 ; i < dq.size() ; ++i)
{
std::cout << i+1 << "\t" << dq[i] << std::endl;
}
}
}
class B
{
public:
double getThreshold() // Non constant for a reason as in real code it isn't
{
return 24.987; // comes from a calculation not needed here so I return a constant.
}
bool Predicate(A_shared_ptr & a)
{
return a->getValueOnWhichToCheck() >= getThreshold();
}
void DoStuff()
{
A_shared_ptr pT1 = std::make_shared<A>(A(2, -6.899987));
A_shared_ptr pT2 = std::make_shared<A>(A(876, 889.878762));
A_shared_ptr pT3 = std::make_shared<A>(A(-24, 48.98924));
A_shared_ptr pT4 = std::make_shared<A>(A(78, -6654.98980));
A_shared_ptr pT5 = std::make_shared<A>(A(6752, 3.141594209));
list_type dq = {pT1,pT2,pT3,pT4,pT5};
PrintDeque(dq);
bool (B::*PtrToPredicate)(A_shared_ptr &) = &B::Predicate;
dq.erase(std::remove_if(dq.begin(), dq.end(), PtrToPredicate),dq.end());
PrintDeque(dq);
}
};
int main()
{
B * pB = new B();
pB->DoStuff();
getchar();
}
g++ -std=c++11 main.cpp -o main
的输出是:
In file included from /usr/include/c++/5/bits/stl_algobase.h:71:0,
from /usr/include/c++/5/bits/char_traits.h:39,
from /usr/include/c++/5/ios:40,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from main.cpp:1:
/usr/include/c++/5/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with _Iterator = std::_Deque_iterator<std::shared_ptr<A>, std::shared_ptr<A>&, std::shared_ptr<A>*>; _Predicate = bool (B::*)(std::shared_ptr<A>&)]’:
/usr/include/c++/5/bits/stl_algo.h:866:20: required from ‘_ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = std::_Deque_iterator<std::shared_ptr<A>, std::shared_ptr<A>&, std::shared_ptr<A>*>; _Predicate = __gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>]’
/usr/include/c++/5/bits/stl_algo.h:936:30: required from ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = std::_Deque_iterator<std::shared_ptr<A>, std::shared_ptr<A>&, std::shared_ptr<A>*>; _Predicate = bool (B::*)(std::shared_ptr<A>&)]’
main.cpp:67:73: required from here
/usr/include/c++/5/bits/predefined_ops.h:234:30: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>*)this)->__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>::_M_pred (...)’, e.g. ‘(... ->* ((__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>*)this)->__gnu_cxx::__ops::_Iter_pred<bool (B::*)(std::shared_ptr<A>&)>::_M_pred) (...)’
{ return bool(_M_pred(*__it)); }
^
您将无法在 remove_if
中使用非静态成员函数指针。 remove_if
需要普通函数指针、静态成员函数指针或函数对象。它不能使用成员函数指针的原因是因为它需要 class 的实例才能调用该函数,而您不能将其包装到调用中
您要么需要创建 Predicate
static
,创建函数对象并传递其实例,要么在调用站点中使用 lambda。
不喜欢函数指针,但使用 lambda 的 this 似乎可以编译...https://ideone.com/0StRcw
dq.erase(std::remove_if(dq.begin(), dq.end(), [this](const std::shared_ptr<A>& a) {
return a->getValueOnWhichToCheck() >= getThreshold();
}),dq.end());
或者没有 lambdas..
auto predicateToUse = std::bind(&B::Predicate, this, std::placeholders::_1);
dq.erase(std::remove_if(dq.begin(), dq.end(), predicateToUse), dq.end());
不自动更新:
dq.erase(std::remove_if(dq.begin(), dq.end(), std::bind(&B::Predicate, this, std::placeholders::_1)), dq.end());