tags:

views:

164

answers:

2

I want to pass an overloaded function to the std::for_each() algorithm. e.g.:

class A {
  void f(char c);
  void f(int i);

  void scan(const std::string& s)
  { std::for_each(s.begin(), s.end(), f); }
};

I'd expect the compiler to resolve f() by the iterator type. Apparently, it (gcc 4.1.2) doesn't do it. So, how can I specify which f() I want?

thanks a lot

+13  A: 

You can use static_cast<>() to specify which f to use according to the function signature implied by the function pointer type:

// Uses the void f(char c); overload
std::for_each(s.begin(), s.end(), static_cast<void (*)(char)>(&f));
// Uses the void f(int i); overload
std::for_each(s.begin(), s.end(), static_cast<void (*)(int)>(&f)); 

Or, you can also do this:

// The compiler will figure out which f to use according to
// the function pointer declaration.
void (*fpc)(char) = &f;
std::for_each(s.begin(), s.end(), fpc); // Uses the void f(char c); overload
void (*fpi)(int) = &f;
std::for_each(s.begin(), s.end(), fpi); // Uses the void f(int i); overload

If f is a member function, then you need to use mem_fun, or for your case, use the solution presented in this Dr. Dobb's article.

In silico
The second method looks very unsafe, is it not?
the_drow
thanks! I still have a problem, though, probably due to the fact that `f()` is a member of a class (see the edited example above)
davka
@the_drow: How so? The function pointer assignment only works if there is an overload that matches the function signature implied by the function pointer declaration.
In silico
ok, now it makes sense (and works :), thanks a lot
davka
@In silico: I misread the code...
the_drow
+4  A: 

Not to answer your question, but am I the only one that finds

for ( int i = 0; i < s.size(); i++ ) {
   f( s[i] );
}

both simpler and shorter than the for_each alternative suggested by in silico in this case?

anon
probably, but it's boring :) also, if I want to use iterator to avoid the [] operator, this becomes longer...
davka
@Davka Boring is what we want. Also, iterators are typically no faster (may be slower) than using op[, if that is your concern.
anon
Algorithms should be preferred to for loops, since they're less error prone and can have better opportunities for optimisation. There's an article on that somewhere... here it is: http://www.drdobbs.com/184401446
AshleysBrain
If you don't have lambdas and auto, iterators can have some serious semantic and syntactic overhead that is just not worth it. If the OP had used a numeric loop, he'd have saved himself time.
DeadMG
@Ashley Until I see some objective stats on the "less error prone" I see no need to believe it. And Meyers in the article appears to talking about loops that use iterators - I'm talking about the efficiency of loops that DON'T use iterators - my own benchmarks tend to suggest that these are marginally faster when optimised - certainly no slower.
anon