Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ostream_iterator and a collection of pointers

12 views
Skip to first unread message

ShaunJ

unread,
Jun 26, 2009, 4:29:45 PM6/26/09
to
I would like to use an ostream_iterator to print the contents of a
collection of pointers. I don't want to print the pointers, however,
but the objects to which they point.

Thanks,
Shaun

Jerry Coffin

unread,
Jun 26, 2009, 5:23:20 PM6/26/09
to
In article <c3bfe697-6e6e-4b8d-9b16-2460796b3480
@a39g2000pre.googlegroups.com>, sjac...@gmail.com says...

> I would like to use an ostream_iterator to print the contents of a
> collection of pointers. I don't want to print the pointers, however,
> but the objects to which they point.

Exactly as stated, I don't think it's possible. If you're willing to
use a proxy class for the pointers, it becomes pretty trivial:

// warning: code only minimally tested.
#include <iostream>

template <class T>
class Proxy {
T ptr;
public:
Proxy(T p) : ptr(p) {}
operator T() { return ptr; }
};

// For this to work 'T' must be a pointer(like) object -- one
// for which unary '*' is supported.
template <class T>
std::ostream &operator<<(std::ostream &os, Proxy<T> p) {
return os << *p;
}

and a quick demo to show it can do the job:

#ifdef TEST
#include <vector>

int main() {
std::vector<Proxy<int *> > ints;

int a = 0, b=1, c=2;

ints.push_back(&a);
ints.push_back(&b);
ints.push_back(&c);

std::copy(ints.begin(),
ints.end(),
std::ostream_iterator<Proxy<int *> >(std::cout, "\n"));
return 0;
}

#endif

I'll leave it to you to decide whether this is really a good idea or
not. It does what you've asked with essentially no overhead, but I'm
still not sure I'd use it in production code. At the very least, I'd
probably rename the Proxy class to something indicating that it's
intended as a proxy for pointers. With support for concepts, we could
include (in real code) some assurance that T is dereferencable, but
as it stands right now, we only have comments to assure that (along
with the fact that otherwise code using it won't compile, but the
error messages may be a bit ugly.

--
Later,
Jerry.

Jerry Coffin

unread,
Jun 26, 2009, 5:32:21 PM6/26/09
to
In article <MPG.24aeea302...@news.sunsite.dk>,
jerryv...@yahoo.com says...

[ ... ]

> // For this to work 'T' must be a pointer(like) object -- one
> // for which unary '*' is supported.

Thinking about it a moment longer, in this case we can enforce that
restriction (without Concepts). We just change operator<< to look
like:
template <class T>
std::ostream &operator<<(std::ostream &os, Proxy<T *> p) {
return os << *p;
}

--
Later,
Jerry.

Bart van Ingen Schenau

unread,
Jun 28, 2009, 12:04:16 PM6/28/09
to
ShaunJ wrote:

You could use std::transform to copy the collection to the stream and
dereference the contents in one go:

struct Dereference
{
template <typename T>
const T& operator()(const T* item) const
{ return *item; }
};

std::transform(coll.begin(), coll.end(),
std::ostream_iterator<T>(stream, ""), Dereference());

>
> Thanks,
> Shaun

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/

ShaunJ

unread,
Jun 30, 2009, 6:02:30 PM6/30/09
to
On Jun 28, 9:04 am, Bart van Ingen Schenau <b...@ingen.ddns.info>
wrote:

> ShaunJ wrote:
> > I would like to use an ostream_iterator to print the contents of a
> > collection of pointers. I don't want to print the pointers, however,
> > but the objects to which they point.
>
> You could use std::transform to copy the collection to the stream and
> dereference the contents in one go:
>
> struct Dereference
> {
> template <typename T>
> const T& operator()(const T* item) const
> { return *item; }
>
> };
>
> std::transform(coll.begin(), coll.end(),
> std::ostream_iterator<T>(stream, ""), Dereference());

Fantastic! This is exactly what I was looking for. Thanks,
Shaun

0 new messages