Re: Generic programming for wrapped types
On Aug 12, 11:42 pm, Alexander Lamaison <aw...@doc.ic.ac.uk> wrote:
Is there a way to write a generic 'algorithm' such that it works both on a
raw type (such as a pointer) and a wrapped type (such as a smart pointer).
... that's all well and good when I'm passing the beginning and the end of
a vector of foo-pointers.
vector<foo*> foos = blah;
do_operation_on_range(foos.begin(), foos.end());
But often I have a vector of smart pointers such as shared_ptr. I cant
just pass the beginning and the end of this vector because the items are
not convertible to foo* by the dereference operator....
What a lot of work just so I can use an algorithm that tries to be generic.
Is there a better way?
The thing is, your "operation" works on a foo* (more likely, on a
foo&, but nevermind that). foo* just isn't whatever_smart_ptr<foo> in
each end every context.
Obviously, first thing is (simple enough) to just write
void operation (const whatever_smart_ptr& P)
{
operation(P.get());
}
In my opinion, anything more than that is an overkill.
Now, I am not particularly good with templates, but this comes to my
mind... You could try to use some kind of proxy object for your
containers and "operations", e.g. (assuming boost::shared_ptr as smart
pointer type and assuming you actually want references, not pointers,
watch out for !!!-marked key parts):
class foo {};
void op(foo& t) {}
template<class T>
struct embedded_proxy
{
embedded_proxy() {}
embedded_proxy(const T& data) : _data(data) {}
T _data;
operator T&() { return _data; }
// !!! used when XXX_proxy is passed from the container to "op"
// (same for other two proxies)
};
template<class T>
struct ptr_proxy
{
ptr_proxy() {}
ptr_proxy(T* data) : _data(data) {}
T* _data;
operator T&() { return *_data; }
};
typedef boost::shared_ptr<foo> SPfoo;
template<class T>
struct sp_proxy
{
typedef boost::shared_ptr<T> SP;
sp_proxy(const SP& data) : _data(data) {}
SP _data;
operator T&() { return *_data; }
};
and then...
std::vector< embedded_proxy<foo> > vec1;
vec1.push_back(foo()); // !!! conversion ctor to embedded_proxy used
std::vector< ptr_proxy<foo> > vec2;
vec2.push_back(new foo()); // // !!! conversion ctor to ptr_proxy used
std::vector< sp_proxy<foo> > vec3;
vec3.push_back(boost::shared_ptr<foo>(new foo()));
// shared_ptr ctor is explicit; blessing or disguise? I say
blessing :-)
// !!! allthough vector elements are XXX_proxies,
// op receives a foo& by going through XXX_proxy::operator foo&
std::for_each(vec1.begin(), vec1.end(), &op);
std::for_each(vec2.begin(), vec2.end(), &op);
std::for_each(vec2.begin(), vec2.end(), &op);
HTH,
Goran.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]