Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2001-01-07 14:35:05


Peter Dimov wrote on 1/7/2001 12:50 PM
>I think that such an "overloading" of a class template is acceptable if
>auto_ptr<T> behaves similarly in the two cases, enabling generic code to
>transparently operate on both variants.
>
>The peculiar semantics of built-in arrays complicate matters even further,
>as this code:
>
>std::auto_ptr<T> p(new T);
>
>doesn't work for T = X[N]. This is perhaps an argument 'for' the
>overloading; but what should the element_type of auto_ptr<X[N]> be?

To tell you the truth, I'm not sure generic programming is very much of
an argument here one way or the other. But yes, auto_ptr<T[]> could be
used in this environment (combined with a few utilities):

template <class T>
void
do_it(T&) // might throw
{
}

template <class T>
void
foo()
{
        typedef typename boost::remove_bounds<T>::type value_type;
        value_type* p;
        std::size_t n = 1;
        if (boost::is_array<T>::value)
        {
                n = 3;
                p = new value_type[n];
        }
        else
                p = new value_type;
        std::auto_ptr<T> ap(p);
        for (int i = 0; i < n; ++i, ++p)
                do_it(*p);
}

int main()
{
        foo<int>();
        foo<int[]>();
}

But auto_array could also be used in a similar situation provided its
interface is sufficiently close to auto_ptr's. You could for example
decide between auto_ptr and auto_array with a traits class:

template <class T>
struct foo_traits
{
        typedef auto_ptr<T> AutoPtr;
};

template <class T>
struct foo_traits<T[]>
{
        typedef auto_ary<T> AutoPtr;
};

template <class T>
void
foo()
{
        typedef typename boost::remove_bounds<T>::type value_type;
        value_type* p;
        std::size_t n = 1;
        if (boost::is_array<T>::value)
        {
                n = 3;
                p = new value_type[n];
        }
        else
                p = new value_type;
        foo_traits<T>::AutoPtr ap(p);
        for (int i = 0; i < n; ++i, ++p)
                do_it(*p);
}

Actually ct_if is probably a better choice than traits:

     ct_if<is_array<T>::value, auto_ary<T>, auto_ptr<T> >::type ap(p);

I still think it is more a matter of which name is more readable or self
documenting.

-Howard


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