I have the following code:
vector<C1*>::iterator itr = vec.begin();
for (; itr != vec.end(); ++itr) {
C2 *c = dynamic_cast<C2*>(*itr);
c->f();
}
I am wondering if I could use one-line for_each to replace it. I tried the following:
for_each(vec.begin(), vec.end(), bind2nd(mem_fun(&C2::f), dynamic_cast<C2*>));
But I get a compile error,
expected unqualified-id before 'dynamic_cast'
What should be the right then?
[EDIT] I cannot use c++11. Looks like I have to define an extra functor, sigh.
For some questionings about the code itself: C1 and C2 are 2 pure interfaces; f() is only available as C2's API. The vector "vec" has a list of objects which have both C1 and C2 interfaces, but they are passed to this piece of code as vector of C1*.
This cast is used for handling polymorphism. You only need to use it when you're casting to a derived class. This is exclusively to be used in inheritence when you cast from base class to derived class.
While typeid + static_cast is faster than dynamic_cast , not having to switch on the runtime type of the object is faster than any of them. Save this answer.
The primary purpose for the dynamic_cast operator is to perform type-safe downcasts. A downcast is the conversion of a pointer or reference to a class A to a pointer or reference to a class B , where class A is a base class of B .
dynamic_cast will no longer throw an exception when type-id is an interior pointer to a value type, with the cast failing at runtime. The cast will now return the 0 pointer value instead of throwing.
Under C++11, instead of doing all this bind
stuff, I would use a lambda:
for_each (vec.begin(), vec.end(), [] (C1* c1)
{
C2* c2 = dynamic_cast <C2*> (c1);
if (c2)
{
c2->f();
}
});
If using C++11 isn't possible, or if for some other reason you shy away from this, then I would construct a functor to wrap this in:
struct call_f
:
public std::unary_function <C1*, void>
{
void operator () (C1* c1) const
{
C2* c2 = dynamic_cast <C2*> (c1);
if (c2)
{
c2->f();
}
}
};
// ...
for_each (vec.begin(), vec.end(), call_f());
dynamic_cast<...>()
may look like a function but it isn't one. You could use something like this:
template <typename T>
struct dynamic_cast_fun {
template <typename F>
T* operator()(F* from) const {
return dynamic_cast<T*>(F* from);
}
};
(possibly with some extra overloads to deal with the constness of the argument).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With