Remve element from vector with lambda - c++

This code does not compile.
std::remove_if( m_selectedFields.begin(),
m_selectedFields.end(),
[](const FieldWin *obj, FieldWin *m_draggingField)
{
obj == m_draggingField;
} );
The m_selectedFields is a vector and its a member of the class, defined as std::vector<Foo *> m_selectedFields.
The m_draggingField is also a member of the class, defined as Foo m_draggingField.
What am I doing wrong?
The errors are:
error C2064: term does not evaluate to a function taking 1 arguments
note: class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
I think lambda function should have only one argument, but then how do I pass the element that needs to be removed?

You need to "capture" this or m_draggingField in the lambda:
std::remove_if( m_selectedFields.begin(),
m_selectedFields.end(),
[this](const FieldWin *obj)
{
obj == m_draggingField;
} );
But if your predicate is really just equality, you can simplify:
std::remove(m_selectedFields.begin(), m_selectedFields.end(), m_draggingField);
Also note that remove and remove_if just reorder elements in the container, you still need to call erase as shown in any tutorial for these functions.

Related

Using find_if and boost::bind with a set of shared_pointers

I have a vector of shared_ptr, I want to combine boost shared_ptr and bind together.
My question is very similar to this, except that instead of "&MyClass::ReferenceFn" I would like to call "&Element::Fn".
Here is a similar piece of code:
typedef boost::shared_ptr< Vertex > vertex_ptr;
std::set<vertex_ptr> vertices;
void B::convert()
{
...
if( std::find_if(boost::make_indirect_iterator(vertices.begin()),
boost::make_indirect_iterator(vertices.end() ), boost::bind( &Vertex::id, boost::ref(*this), _1 ) == (*it)->id() ) == vertices.end() )
}
here is the error:
no matching function for call to ‘bind(<unresolved overloaded function type>, const boost::reference_wrapper<B>, boost::arg<1>&)’
NOTE: I am limited to use the C++03.
To call a member function for each object stored in a collection, you need to use a placeholder as the first bound argument of the boost::bind:
boost::bind(&Vertex::id, _1) == (*it)->id())
// ~^~
This way, each argument a, will be bound to a member function pointer, and called as (a.*&Vertex::id)().
However, seeing that the error message says unresolved overloaded function type, it draws a conclusion that your class Vertex can have multiple overloads of member function id. As such, the compiler is unable to tell which one it should pass as the argument of boost::bind. To solve this, use an explicit cast to a member function pointer (the asterisk after colon indicates it's a pointer to a member):
boost::bind(static_cast<int(Vertex::*)()const>(&Vertex::id), _1) == (*it)->id())
// ~~~~~~~~~~~~~~~~~~~~^
In the case class Vertex has multiple overloads, say:
int id() const { return 0; }
void id(int i) { }
you will use the first one for binding.

no matching function for call to std::list::remove_if( function()::predicate )

So, defining a predicate inside a function and use as std::list::remove_if argument is not allowed?
Consider the following code, which fails to compile:
struct a { };
int main()
{
struct pred { bool operator()( const a& ) { return false; } };
std::list< a > l; // fill l
l.remove_if( pred() );
return 0;
}
error: no matching function for call to
‘std::list<a, std::allocator<a> >::remove_if(main()::pred)’
Now, if I replace l.remove_if( pred() ); with
pred()( *l.begin() );
// or
pred p;
p( *l.begin() );
which remove_if does internally, it compiles and works as expected.
And even more: if I move struct pred to be defined outside main, both tests work as expected.
This doesn't make any sense to me.
I thought that it could be something with dependent names and ADL and things like this, but... the argument of remove_if is an instance, not a type. It's true, that this is a template function and the argument's type is still resolved, but..
Can somebody explain what and why happens?
The answer to your very first question is that yes, prior to C++11 some types (such as local types) are NOT allowed as template parameters. See 14.3.1/2:
A local type, a type with no linkage, an unnamed type or a type
compounded from any of these types shall not be used as a
template argument for a template type parameter.
Since remove_if is a template, you cannot use the local predicate as its parameter.

What's the difference between a Predicate and a Functor?

I just read somebody call a class with a constructor and an operator() a predicate:
// Example
class Foo {
public:
Foo(Bar);
bool operator()(Baz);
private:
Bar bar;
};
However, I haven't heard the word predicate being used in this context before. I would call such a thing a functor. For me, a predicate would be something from the domain of formal logic.
This raises the following questions:
Is this a common word for something like Foo?
Are both terms used interchangeably, or do they mean slightly different things?
Or
Does the return type (bool versus something else) have something to do with it?
What about the operator() being const?
Functor is a term that refers to an entity that supports operator () in expressions (with zero or more parameters), i.e. something that syntactically behaves as a function. Functor is not necessarily an object of some class with overloaded operator (). Ordinary function names are functors as well. Although in some contexts you can see the term "functor" used in a more narrow and exclusive sense: just class objects, but not ordinary functions.
A predicate is a specific kind of functor: a functor that evaluates to a boolean value. It is not necessarily a value of bool type, but rather a value of any type with "boolean" semantics. The type should be implicitly convertible to bool though.
The shown class is a functor that implements a predicate.
A predicate is a boolean function.
About the operator() being non-const here: it should ideally be const, yes.
A predicate is a special kind of function object. See this excellent column by Nicolai Josuttis. To quote:
A function object that returns a Boolean value is a predicate. That's
what almost all tutorials, books, and manuals write about predicates
of the STL. This, however, is not the whole story.
However, there is an additional requirement that is unfortunately not
mentioned in any manual or in the C++ Standard: A predicate should
always return the same result for the same value.
Or, in the language of C++: You should declare operator() as a
constant member function (and not play games with mutable or casts).
For the same reason, a copy of a predicate should have the same state
as the original.
The reason is that the STL algorithms will copy function objects around, and the copying should not affect the outcome of applying the function objects.
template<typename Arg0>
struct UnaryPredicate
:
public std::function<bool(Arg0 const&)>
{
bool operator()(Arg0 const& a0) const
{
return // your code here
}
};
template<typename Arg0, typename Arg1>
struct BinaryPredicate
:
public std::function<bool(Arg0 const&, Arg1 const&)>
{
bool operator()(Arg const& a0, Arg const& a1) const
{
return // your code here
}
};
As has been said, a predicate is just a user supplied directive to analyze something to a boolean state. So you can have the same two things doing the same thing...
struct is_odd
{
is_odd() : count(0);
bool operartor () (int i) const { ++count; return (i % 2) == 1; }
private
int count;
}
And...
bool isOdd(int i) { return (i % 2) == 1; }
So, what is so special about the functor? It maintains state if you want it to! That means that while these two lines of code do the same thing (assume v is a vector, with values 0 - 9)...
for_each(v.begin(), v.end(), isOdd); //using C-style function pointer
And...
is_odd fn = for_each(v.begin(), v.end(), is_odd); //using functor
Only with the second use case can you then call...
int calls = fn.count;
That is because for_each (as well as other STL algorithm functions) returns the functor it used at the end, so now the final state can be queried.
One other cool thing to note is that in the second case, we are using what is called an "anonymous" object.
From the MSDN:
Represents the method that defines a set of criteria and determines
whether the specified object meets those criteria.
http://msdn.microsoft.com/en-us/library/bfcke1bz.aspx

Correct Way to Define a Predicate Function in C++

I'm trying to write predicate function for use with STL algorithms. I see that they are two ways to define a predicate:
(1) Use a simple function as below:
bool isEven(unsigned int i) { return (i % 2 == 0); }
std::find_if(itBegin, itEnd, isEven);
(2) Use the operator() function as below:
class checker {
public:
bool operator()(unsigned int i) { return (i % 2 == 0); }
};
std::find_if(itBegin, itEnd, checker);
I have more use for the second type as I usually would like to create a predicate object with some members in it and use them in the algorithm. When I add the same isEven function inside checker and use it as a predicate, I get an error:
3. Syntax which gives error:
class checker {
public:
bool isEven(unsigned int i)
{ return (i%2 == 0); }
};
checker c;
std::find_if(itBegin, itEnd, c.isEven);
Calling c.isEven gives an error during compilation saying undefined reference to some function. Can someone explain why 3. is giving error? Also, I would appreciate any pointers to read about predicate and iterator basics.
A pointer to a member function requires an instance to be called on, and you are passing only the member function pointer to std::find_if (actually your syntax is incorrect, so it doesn't work at all; the correct syntax is std::find_if(itBegin, itEnd, &checker::isEven) which then still doesn't work for the reasons I gave).
The find_if function expects to be able to call the function using a single parameter (the object to test), but it actually needs two to call a member function: the instance this pointer and the object to compare.
Overloading operator() allows you to pass both the instance and the function object at the same time, because they're now the same thing. With a member function pointer you must pass two pieces of information to a function that expects only one.
There is a way to do this using std::bind (which requires the <functional> header):
checker c;
std::find_if(itBegin, itEnd, std::bind(&checker::isEven, &c, std::placeholders::_1));
If your compiler doesn't support std::bind, you can also use boost::bind for this. Though there's no real advantage to doing this over just overloading operator().
To elaborate a bit more, std::find_if expects a function pointer matching the signature bool (*pred)(unsigned int) or something that behaves that way. It doesn't actually need to be a function pointer, because the type of the predicate is bound by the template. Anything that behaves like a bool (*pred)(unsigned int) is acceptable, which is why functors work: they can be called with a single parameter and return a bool.
As others have pointed out, the type of checker::isEven is bool (checker::*pred)(unsigned int) which doesn't behave like the original function pointer, because it needs an instance of checker to be called on.
A pointer to a member function can be conceptually considered as a regular function pointer that takes an additional argument, the this pointer (e.g. bool (*pred)(checker*, unsigned int)). You can actually generate a wrapper that can be called that way using std::mem_fn(&checker::isEven) (also from <functional>). That still doesn't help you, because now you have a function object that must be called with two parameters rather than only one, which std::find_if still doesn't like.
Using std::bind treats the pointer to a member function as if it was a function taking the this pointer as its first argument. The arguments passed to std::bind specify that the first argument should always be &c, and the second argument should bind to the first argument of the newly returned function object. This function object is a wrapper that can be called with one argument, and can therefore be used with std::find_if.
Although the return type of std::bind is unspecified, you can convert it to a std::function<bool(unsigned int)> (in this particular case) if you need to refer to the bound function object explicitly rather than passing it straight to another function like I did in my example.
I guess it's because the type of c.isEven() is,
bool (checker::*)(unsigned int) // member function of class
which may not be expected by find_if(). std::find_if should be expecting either a function pointer (bool (*)(unsigned int)) or a function object.
Edit: Another constraint: A non-static member function pointer must be called by the class object. In your case, even if you succeed to pass the member function then still find_if() will not have any information about any checker object; so it doesn't make sense to have find_if() overloaded for accepting a member function pointer argument.
Note: In general c.isEven is not the right way to pass member function pointer; it should be passed as, &checker::isEven.
checker::isEven is not a function; it is a member function. And you cannot call a non-static member function without a reference to a checker object. So you can't just use a member function in any old place that you could pass a function pointer. Member pointers have special syntax that requires more than just () to call.
That's why functors use operator(); this makes the object callable without having to use a member function pointer.
I prefer functors (function objects) because make your program more readable and, more importantly, expressing the intent clearly.
This is my favorite example:
template <typename N>
struct multiplies
{
N operator() (const N& x, const N& y) { return x * y; }
};
vector<int> nums{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Example accumulate with transparent operator functor
double result = accumulate(cbegin(nums), cend(nums), 1.1, multiplies<>());
Note: In recent years we've got a lambda expression support.
// Same example with lambda expression
double result = accumulate(cbegin(nums), cend(nums), 1.1,
[](double x, double y) { return x * y; });
The example given says you should use the call operator (operator()) whereas in your example you've called your function isEven. Try re-writing it as:
class checker {
public:
bool operator()(unsigned int i)
{ return (i%2 == 0); }
};

Returning a priority_queue with custom comparator

I have a function that needs to return a sorted list based on some input parameters. I've selected a std::priority_queue to hold this list.
But the compiler is giving me an error I don't recognize. Here's the code I have:
struct DepthCompare {
bool operator()
(const struct inst *&lhs, const struct inst *&rhs) const
{
return lhs->depth < rhs->depth;
}
};
typedef priority_queue<struct inst*> HeuristicList;
HeuristicList getHeuristicList(struct BasicBlock &) {
HeuristicList ret( DepthCompare );
return ret;
}
The compiler says that a conversion from 'HeuristicList (*)(DepthCompare)' to non-scalar type 'HeuristicList' requested on the return statement's line.
It doesn't look like I'm trying to return a pointer. What's going wrong?
You have two problems.
To use a custom comparator, you must specify the comparator type as the third template argument:
typedef priority_queue<inst*, vector<inst*>, DepthCompare> HeuristicList;
HeuristicList ret( DepthCompare ); is interpreted as a function declaration, rather than a variable declaration, giving the error that you're seeing. You need to pass an instance of the comparator, and make sure it can't be interpreted as a function declaration:
HeuristicList ret = HeuristicList(DepthCompare());
However, since the constuctor's first argument is optional, and defaults to a default-constructed comparator, you can simply write
HeuristicList ret;
Or, since you're just returning the variable straight away,
return HeuristicList();
Note that the comparator is the third template parameter of priority_queue. You must declare your priority_queue like such:
typedef priority_queue<inst*, vector<inst*>, DepthCompare> HeuristicList;
This assumes you want to use vector as the backing container (default).
Also note that in your comparator functor, you want to declare the parameters as const reference to a pointer. What you have is a reference to a pointer to const. You want this:
bool operator()(inst* const& lhs, inst* const& rhs) const
You also don't need to pass an instance of your comparator object to the priority_queue constructor, as the default comparator constructor will do just fine.