Re: STL algorithm member function problem
Markus Moll wrote:
Hi
lists@givemefish.com wrote:
I want to iterate over all the rules in the list and apply them to the
filename list using the remove_if algorithm. But I am having trouble
with the remove_if call.
Thus the code looks something like this:
class Rule : public std::unary_function<std::string, bool> {
public:
virtual result_type operator()(const argument_type&) const =0;
};
typedef boost::shared_ptr<Rule> RulePtr;
This means "Rule" should have a virtual destructor.
Thanks. It actually does, but to keep everything brief, I condensed
all the code.
vector<string> fileList;
// .... fill fileList with a series of file names ...
//Now remove items from the fileList according to the rules.
//Iterate over all the rules in the rules vector. Apply the rule
to each of
// items in the fileList and remove it if the rule returns true.
for(vector<RulePtr>::const_iterator ruleIter = m_rules.begin();
ruleIter != m_rules.end(); ++ruleIter) {
// This is the problem line...
std::remove_if(fileList.begin(), fileList.end(), ptr_fun(
xxx );
}
Two problems:
1. remove_if is not doing what you think it does. remove_if(b,e,pred)
returns an iterator k such that the range [b,k) contains those elements x
for which pred(x) is false. Nevertheless, no elements are actually removed
from the underlying container (you couldn't, only given the iterators. And
maybe you couldn't at all. Consider int arr[42] }
Thanks.
2. ptr_fun is not doing what you think it does. It is just a wrapper around
ordinary pointers to functions, so that you suddenly have the member
typedefs argument_type and result_type. The predicate you are looking for
is *ruleIter.
Correcting both, we get:
vector<string>::iterator current_end = fileList.end();
for(vector<RulePtr>::const_iterator ruleIter = m_rules.begin();
ruleIter != m_rules.end(); ++ruleIter) {
current_end = std::remove_if(fileList.begin(), current_end, *ruleIter);
}
// you might want to erase trailing garbage...
fileList.erase(current_end, fileList.end());
Markus
This doesn't work, however. Derefencing the iterator returns a
RulePtr, which is typedef'd as a boost::shared_ptr<Rule>. Derefencing
this, i.e., (*(*ruleIter)), results in an error that the compiler
cannot construct the abstract base class Rule.
Thanks,
Matt.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]