2017-01-18 39 views
4

this回答T.C.狀態什麼是未知大小的make_shared?

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有什麼區別?兩者似乎都創建了一個int大小數組30.

回答

2

這個例子並不好。通過未知大小的陣列,他們推測意味着它可以以下面的方式來調用:

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

由於arr2_size可以動態地定義它可以被認爲是「未知」。

其次它們都創建一個大小爲30的數組,但sh_arr3包含類型本身的大小,如果訪問超出邊界,編譯器將發出警告。沒有明確大小的類型將無法檢測到這些情況。

1

首先,make_shared如何支持未知大小的數組類型?我想 會認爲數組大小是必需的。

Boost使用輔助類來確定其shared_ptr::operator[](...)的返回類型。它還使用其他輔助類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 

二,什麼是sh_arr2和sh_arr3之間的區別?這兩個似乎 將創建一個int大小數組30.

第二個包括範圍檢查。從Boost docs

與升壓釋放1.53開始,shared_ptr的可用於一個 指針保持到動態分配的數組。這通過 使用數組類型(T []或T [N])作爲模板參數來完成。有一個 幾乎沒有區別使用一個未分類的數組,T [],和一個大小爲 數組,T [N];後者只是使運算符[]能夠對索引執行範圍 檢查。