Re: Using mem_fun_ref on overloaded member function.
tmak wrote:
Thanks for your help SG. The functor approach worked for me.
I modified it by making a template function "for_all" instead to avoid
needing the bind2nd call, as well as having to specify the argument
type to appendor.
Here's my final version (please comment if you see a problem -I'm
trying to learn templates);
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
template<typename T> class appendor
{
public:
template<class A>
T& operator()(T& t, const A& a) const {return t.append(a);}
template<class A>
T& operator()(T& t, A& a) const {return t.append(a);}
};
template<class V,class F,class A>
void for_all(V& vec,const F& func,const A& arg)
{
for (typename V::iterator it=vec.begin(); it != vec.end(); it ++)=
{
func(*it,arg);
}
}
V might be deduced to be "const something" in which case begin() and
end() will return const_iterators. const_iterators are not convertible
to their non-const counter part, so this will result in a compilation
error. Also, avoid post-increment and post-decrement if pre-increment
or pre-decrement is sufficient.
In C++0x you will be able to write
template<class Container, class Functor, class...Args>
Functor for_all(Container & cont, Functor f, const Args&...args)
{
auto beg = vec.begin();
auto const end = vec.end();
for (; beg!=end; ++beg){
func(*beg,args...);
}
return func;
}
to solve the iterator type problem. But then again, you could just as
well reuse std::for_each with a lambda expression or use the new for-
range loop.
In C++03 you can overload your for_all function template with another
version that takes a ref-to-const for the container and use typename
Container::const_iterator as iterator type. Another approach would be
to write a "trait class" like this:
template<typename Container>
struct get_iterator_type
{typedef typename Container::iterator type;};
template<typename Container>
struct get_iterator_type<const Container>
{typedef typename Container::const_iterator type;};
template<class Container, class Functor, class Arg>
Functor for_all(Container & cont, Functor f, const Arg& arg)
{
typedef typename get_iterator_type<Container>::type iter_t;
iter_t beg = vec.begin();
iter_t const end = vec.end();
for (; beg!=end; ++beg){
func(*beg,arg);
}
return func;
}
Cheers!
SG