Reputation: 2014
I think everyone has experience working with a code like the following:
void fun(Type1&);
void fun(Type2&);
vector<Type1> vec;
for_each(vec.begin(), vec.end(), fun);
Of course that won't compile, because it's not clear which function to be passed. And what's your commonly-used solution to the problem?
I know this will work:
for_each(vec.begin(), vec.end(), (void(*)(Type1&))fun);
But any better ideas?
Upvotes: 2
Views: 170
Reputation: 730
I'd like to second Kirill's answer. If fun() functions are implemented very similarly (same code involving different types), it's a good idea to rewrite them as one single template function. As an additional plus, you would get a possibility to elegantly specify the function you need.
It's usually recommended to use the C++ equivalent to the C-style type cast:
for_each(vec.begin(), vec.end(), reinterpret_cast<void(*)(Type1&)>(fun));
Even more appropriate is to use static_cast in this case:
for_each(vec.begin(), vec.end(), static_cast<void(*)(Type1&)>(fun));
since we want to hint the compiler to the proper type.
Although much more verbose, it's better simply for code maintenance reasons -- it's easier to search for such constructs in the code than for C-style type casts.
There is also a possibility to avoid using type casts in favor of an explicit template argument specification:
for_each<std::vector<A>::iterator, void(*)(Type1&)>(vec.begin(), vec.end(), fun);
-- although it's not very big improvement from the original code. As you can see, you have to explicitly specify the first template parameter as well.
Upvotes: 0
Reputation: 99685
One solution is to use template function:
template<typename T>
void fun(T&);
// specialize fun for Type1 and Type2
...
for_each(vec.begin(), vec.end(), fun<Type1>);
The better way is to use functor with template operator()
:
struct fun
{
template<typename T>
void operator()(T&) const;
};
...
for_each(vec.begin(), vec.end(), fun()); // T for operator() will be deduced automatically
Upvotes: 2