|
Boost : |
From: Eric Friedman (ebf_at_[hidden])
Date: 2003-10-28 15:01:33
E. Gladyshev wrote:
> struct visitor
> {
> template< typename T >
> operator()( T& x )
> {
> x.f();
> };
> operator()( boost::empty& ) {}
> };
>
> It becames even more interesting for binary visitors.
> All your visitors will need boost::empty overloads
> and you would have to make sure that you are not
> using types any other non-throw types to do
> the optimization trick.
>
> struct visitor
> {
> template< typename T, typename U >
> operator()( T& x, U& u )
> {
> x.f( u ); //general function
> };
> //optimization stuff
> template<typename U> operator()( boost::empty&, U& );
> template<typename T> operator()( T&, boost::empty& );
> void operator()( boost::empty&, boost::empty& );
> };
>
> I guess I can live with it for now.
Yes, the idea of not allowing singular state is that the user is forced
to deal with the possibility that the variant contains boost::empty.
If you really wanted, you could write something as follows (not tested):
template <typename VisitorBase, typename T>
struct cannot_visit
: VisitorBase
{
typedef typename VisitorBase::result_type result_type;
result_type operator()(const T&) const
{ throw boost::bad_visit(); }
template <typename U>
result_type operator()(const T&, const U&) const
{ throw boost::bad_visit(); }
template <typename U>
result_type operator()(const U&, const T&) const
{ throw boost::bad_visit(); }
};
Which would then be used like this:
struct my_visitor
: cannot_visit<
boost::static_visitor<R>, boost::empty
>
{
using cannot_visit::operator();
template <typename T>
R operator()(const T& t)
{
return t.f(); // or whatever
}
};
If this is found useful, I could even modify static_visitor to permit
the following syntax:
struct my_visitor
: static_visitor< R, cannot_visit<boost::empty> >
{
using static_visitor::operator();
...
};
Eric
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk