jacknad
jacknad

Reputation: 13739

What is make_shared of unknown size?

In this answer T.C. states

boost::make_shared etc. support array types - either one of unknown size, or one of fixed size

boost::shared_ptr<int[]> sh_arr2 = boost::make_shared<int[]>(30);
boost::shared_ptr<int[30]> sh_arr3 = boost::make_shared<int[30]>();

First, how can make_shared support an array type of unknown size? I would think the array size is required.

Second, what is the difference between sh_arr2 and sh_arr3? Both seem to be creating an array of int size 30.

Upvotes: 4

Views: 358

Answers (2)

WhiZTiM
WhiZTiM

Reputation: 21576

First, how can make_shared support an array type of unknown size? I would think the array size is required.

Boost uses a helper class to determine the return type of its shared_ptr::operator[](...). It also uses another helper class boost::detail::sp_extent which provides specializations for array types to determine bounds (if T can be decomposed to T[]), Here is a summarized snippet from http://www.boost.org/doc/libs/1_63_0/boost/smart_ptr/shared_ptr.hpp :

namespace boost{
template<typename T>
class shared_ptr{
   .....
    typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
        {
            BOOST_ASSERT( px != 0 );
            BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );

            return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
        }
    ....
}

namespace detail{

    template< class T > struct sp_array_access
    { typedef void type; };

    template< class T > struct sp_array_access< T[] >
    { typedef T & type; };

    template< class T, std::size_t N > struct sp_array_access< T[N] >
    { typedef T & type; };



    template< class T > struct sp_extent
    { enum _vt { value = 0 }; };

    template< class T, std::size_t N > struct sp_extent< T[N] >
    { enum _vt { value = N }; };
}//end namepace detail
}//end namespace boost

Second, what is the difference between sh_arr2 and sh_arr3? Both seem to be creating an array of int size 30.

The second includes range checking. From Boost docs:

Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamically allocated array. This is accomplished by using an array type (T[] or T[N]) as the template parameter. There is almost no difference between using an unsized array, T[], and a sized array, T[N]; the latter just enables operator[] to perform a range check on the index.

Upvotes: 1

Kiskae
Kiskae

Reputation: 25573

The example isn't that great. By an array of unknown size they presumably mean it can be invoked in the following way:

int arr2_size = 30;
boost::shared_ptr<int[]> sh_arr2 = boost::make_shared<int[]>(arr2_size);

Since arr2_size can be dynamically defined it can be considered 'unknown'.

Secondly they do both create an array of size 30, but sh_arr3 contains the size in the type itself which will allow the compiler to emit warnings if access goes outside of the bounds. The type without an explicit size will not be able to detect those cases.

Upvotes: 2

Related Questions