4

这个答案 TC 状态

boost::make_shared等支持数组类型-未知大小之一或固定大小之一

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有什么区别?两者似乎都在创建一个大小为 30 的 int 数组。

4

2 回答 2

2

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

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

由于arr2_size可以动态定义,因此可以将其视为“未知”。

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

于 2017-01-18T13:23:58.900 回答
1

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

Boost 使用辅助类来确定其shared_ptr::operator[](...). 它还使用另一个帮助类boost::detail::sp_extent,它为数组类型提供特化来确定边界(如果T可以分解为),这是来自http://www.boost.org/doc/libs/1_63_0/boost/smart_ptr/shared_ptrT[]的摘要片段.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

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

第二个包括范围检查。来自Boost 文档

从 Boost 1.53 版开始,shared_ptr 可用于保存指向动态分配数组的指针。这是通过使用数组类型(T[] 或 T[N])作为模板参数来实现的。使用无大小数组 T[] 和大小数组 T[N] 几乎没有区别;后者只是使 operator[] 能够对索引执行范围检查。

于 2017-01-18T14:00:09.317 回答