Boost logo

Boost :

From: bill_kempf (williamkempf_at_[hidden])
Date: 2002-02-22 17:52:15


--- In boost_at_y..., Douglas Gregor <gregod_at_c...> wrote:
> On Tuesday 19 February 2002 06:19 pm, you wrote:
> > * I'd like to see discussion of the visit_each() template in the
> > Boost.Signals Design page. Each a very powerful and useful little
> > template and hasn't been given enough visibility in the
> > documentation. It's a useful concept for things other then the
> > Boost.Signals library implementation. (I personal request would
be
> > for you to make the reasons for the use of the third parameter
more
> > clear.) BTW, the documentation for visit_each() states the third
> > parameter type to be int, while the description mentions long and
the
> > actual source uses long.
>
> That last parameter is a bit vexing, and deserves more
documentation than it
> has. It's a hack to get around the lack of partial ordering of
function
> templates. Consider:
>
> template<typename> class A {};
> template<typename T> void foo(T);
> template<typename T> void foo(A<T>);
> A<T> at;
> foo(at);
>
> Without partial ordering of function templates, the call on the
fifth line
> will be ambiguous. However, one can do this:
>
> template<typename> class A {};
> template<typename T> void foo(T, long);
> template<typename T> void foo(A<T>, int);
> A<T> at;
> foo(at, 0);
>
> Even though the dumb compiler can't figure out that A<T> is better
than T, it
> can figure out that int -> int is better than int->long, so it
chooses the
> specialization.
>
> I'll add this to the documentation.

I've been playing around with this, and I have a slight suggestion to
make the interface nicer for users (instead of implementors).
Another "wrapper" removes the need to supply the third parameter when
calling visit_each, so the knowledge of why this is necessary and how
to use it can be limited to only those that are providing a
specialized version of visit_each for a given T.

template <typename Visitor, typename T>
void visit_each(Visitor& v, T const & t, long)
{
   v(t);
}

template <typename Visitor, typename T>
void visit_each(Visitor& v, T const & t)
{
   visit_each(v, t, 0);
}

template <typename Visitor>
void visit_each(Visitor& v, foo const & f, int) // still has to know
{
   std::cout << "foo: " << f << std::endl;
   v(f);
}

foo f;
my_visitor v;
visit_each(v, f);

Thoughts?

Bill Kempf


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk