Re: mem_fun and smart pointers?
On 5 Mrz., 20:28, "Hak...@gmail.com" <hak...@gmail.com> wrote:
#include <vector>
#include <algorithm>
#include <functional>
#include <tr1/memory> // Just <memory> in MSVC.
using namespace std;
using namespace tr1;
struct A {
virtual void f() {
}
};
int main()
{
vector< shared_ptr<A> > vec;
for_each( vec.begin(), vec.end(), mem_fun( &A::f ) );
}
The error i get is long, but what i believe is relevant: "error: no
match for call to (std::mem_fun_t<void, A>)
(std::tr1::shared_ptr<A>&) " and "candidates are: _Ret
std::mem_fun_t<_Ret, _Tp>::operator()(_Tp*) const [with _Ret = void,
_Tp = A]" .
I need no explaining on how mem_fun_t expects a straight pointer and
i'm not using it properly, but what i'm here questioning is why.
Should i not expect that this code to work? Is there a reason that
mem_fun_t SHOULD NOT accept a pointer object?
IMO there is no fundamental reason why this should not work.
Is there an alternative
or replacement i am ignorant of? Is there an entirely different or
more correct way to do this? Is there a library addition (not language
feature, like lambdas) in C++0x that does what i expect?
The latter: In C++0x you will have mem_fn available, it's
also part of boost. In principle, it will be a generalized
version of mem_fun and mem_fun_ref, therefore there are
little chances that mem_fun will be fixed to make it work.
Consider mem_fn being a set of overloaded function templates,
among them this one:
template<class R, class T, class ...Args>
/unspecified/ mem_fn(R (T::* pm)(Args...));
(of-course all pointer-to-member with cv-qualifications
and ref-qualifiers will be supported as well, plus pointer
to data member or shorter: The whole member-to-pointer
"shebang" ;-)
The function object type returned has to support several
calling conventions described by a hypothetical INVOKE
construct with function-like character:
INVOKE(f, t1, t2, ..., tN)
described in 20.8.2 [func.require].
In your example the second bullet applies:
"Define INVOKE(f, t1, t2, ..., tN) as follows:
? (t1.*f)(t2, ..., tN) when f is a pointer to a
member function of a class T and t1 is an object
of type T or a reference to an object of type T
or a reference to an object of a type derived
from T;
? ((*t1).*f)(t2, ..., tN) when f is a pointer to a
member function of a class T and t1 is not one of
the types described in the previous item;
[..]
"
You will recognize that the second bullet just works,
because shared_ptr provides an operator* overload
that will be used for dereferencing such an object.
I could use the C++0x features of g++ like lambdas to dereference the
shared_ptr before calling A::f, or (and this is what i ended up doing
in my application) i could write a for_each_ptr that expects an
iterator object and dereferences it before calling f. I'm preferring
to use std:: for simplicity and elegance, but also preferring not to
use C++0x for compatibility reasons.
Yes, I agree that you should not be required to refer
to extra language features for such a thing.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]