Learning functors problem. Pointer to reference
Hi...I've been playing around trying to learn bind1st, mem_fun, ptr_fun, etc. and I noticed that my code I always have collections of pointers, not objects (maybe this is bad?). So I thought a functor to dereference the pointer and apply the function would be useful e.g.
Code:
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
// functor to dereference argument before applying the unary_function
template<class Op>
class deref_and_apply : public unary_function<typename Op::argument_type*,
typename Op::result_type>
{
public:
deref_and_apply(const Op& op) : m_op(op) { }
typename Op::result_type operator() (const typename Op::argument_type* p)
{
return m_op(*p);
}
protected:
Op m_op;
};
template <class Op>
inline deref_and_apply<Op> derefapply(const Op& op)
{ return deref_and_apply<Op>(op); }
int main()
{
vector<const int*> l_list1;
l_list1.push_back(new int(1));
l_list1.push_back(new int(13));
l_list1.push_back(new int(42));
vector<const int*>::iterator l_itr = find_if( l_list1.begin(), l_list1.end(),
derefapply( bind2nd(greater<int>(),7) ) );
if (l_itr != l_list1.end() )
{
cout << "FOUND " << **l_itr << "\n";
}
return 0;
}
This works, but then I tried the following and I found I couldn't stop the copy of the Node object before being passed to the Printer functor. I get a "pointer to reference" error.
Code:
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
// Simple test class
struct Node {
Node(const Node& n) : m_id(n.m_id) { cout << "COPY NODE " << m_id << "\n"; }
Node(int id) : m_id(id) { }
int m_id;
};
ostream& operator<<(ostream& os, const Node& n) { return os << "NODE " << n.m_id << "\n"; }
// Send object of type T to ostream
template <typename T>
class Printer : public unary_function<T, void> {
public:
Printer(ostream& rOS) : m_os(rOS) { }
void operator()(const T t) { m_os << t; }
protected:
ostream& m_os;
};
// functor to dereference argument before applying the unary_function
template<class Op>
class deref_and_apply : public unary_function<typename Op::argument_type*,
typename Op::result_type>
{
public:
deref_and_apply(const Op& op) : m_op(op) { }
typename Op::result_type operator() (const typename Op::argument_type* p)
{
return m_op(*p);
}
protected:
Op m_op;
};
template <class Op>
inline deref_and_apply<Op> derefapply(const Op& op)
{ return deref_and_apply<Op>(op); }
int main()
{
vector<const Node*> l_list1;
l_list1.push_back(new Node(1));
l_list1.push_back(new Node(2));
vector<Node> l_list2;
l_list2.push_back(Node(10));
l_list2.push_back(Node(20));
// This will copy each node before passing to Printer
for_each(l_list1.begin(), l_list1.end(), derefapply( Printer<const Node>(cout) ));
//XXX This doesn't compile. Pointer to reference error
//for_each(l_list1.begin(), l_list1.end(), derefapply( Printer<const Node&>(cout) ));
// This doesn't copy the objects
for_each(l_list2.begin(), l_list2.end(), Printer<const Node&>(cout) );
return 0;
}
I guess my questions are
1) Is there a way to get the derefapply to work without a copy of the Node?
2) In my investigations I got this error a lot. Am I missing something fundamental about how to structure and use this stuff e.g. should I not use collections of pointers?
3) I notice at the end (just above the conclusion) of this article http://www.ddj.com/cpp/184401746 it mentions problems with references to references and says boost provides better functionality. Am I just looking at this too simplistically and to do this kind of generic programming you need a lot more and smarter code than my simple test?
Thanks,
Stuart.