什么是未知大小的 make_shared?

What is make_shared of unknown size?

回答T.C。州

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]>();

首先,make_shared如何支持未知大小的数组类型?我认为数组大小是必需的。

其次,sh_arr2和sh_arr3有什么区别?两者似乎都在创建一个 int 大小为 30 的数组。

这个例子不是很好。通过未知大小的数组,他们大概意味着它可以通过以下方式调用:

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

因为arr2_size可以动态定义所以可以考虑'unknown'.

其次,它们都创建了一个大小为 30 的数组,但 sh_arr3 包含类型本身的大小,这将允许编译器在访问超出范围时发出警告。没有明确大小的类型将无法检测到这些情况。

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

Boost 使用助手 class 来确定其 shared_ptr::operator[](...) 的 return 类型。它还使用另一个助手 class boost::detail::sp_extent 数组类型 提供特化来确定边界(如果 T 可以分解为 T[] ), 这是来自 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.

第二个包括范围检查。来自 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.