2013-07-25 45 views
6

C++ 11提供了std::allocator_traits類作爲使用分配器的標準方式。靜態功能std::allocator_traits::construct()需要指針到應該構建對象的位置。然而,std::allocator_traits::allocate()靜態函數會返回一個值allocator::pointer,該值只需要像指針一樣工作,但不一定是一個(一般來說,儘管std::allocator::pointer必須是指針)。allocator_traits :: construct()vs allocator_traits :: allocate()

如果一般情況下他們會使用不兼容的類型,應該如何使用分配和構造靜態方法?只有在pointer類型實際可轉換爲普通的普通指針時纔可以使用它們嗎?

+0

+1這是一個非常有見地的問題。有很少的C++程序員在探索這些水域。執行者必須。這導致我問這個問題:你是一個std :: lib實現者嗎? –

+0

@HowardHinnant:謝謝!這個問題與一個小型矢量類的設計相關,它在std :: vector上有一些額外的花招和口哨聲(例如,自動使用多達幾個元素的靜態存儲,支持SSE和其他矢量指令等)。只是想嘗試在分配器支持方面採取「適當」的方式。 – bluescarni

回答

4

有兩種技術可以做到這一點,這取決於你目前的狀況。

如果你有一個左值表達式,說,在一個節點的值字段,那麼你可以使用std :: addressof像這樣:

allocator_traits<allocator_type>::construct(alloc, std::addressof(ptr->value), ...); 

其中ptrallocator_type::pointer

但是,如果你沒有取消引用一個字段,要轉換一個allocator_type::pointerT*,有您需要首先實現了一招:

template <class T> 
inline 
T* 
to_raw_pointer(T* p) noexcept 
{ 
    return p; 
} 

template <class Pointer> 
inline 
typename std::pointer_traits<Pointer>::element_type* 
to_raw_pointer(Pointer p) noexcept 
{ 
    return p != nullptr ? ::to_raw_pointer(p.operator->()) 
         : nullptr; 
} 

現在你可以說:

allocator_traits<allocator_type>::construct(alloc, to_raw_pointer(ptr), ...); 
+0

哦,哇,永遠不會完成學習...''operator - >()''的語義是非常令人難以置信的:D – bluescarni

+0

歡呼,順便說一句,答案已被接受。 – bluescarni

+0

爲什麼要在'to_raw_pointer(p.operator - >())'前寫'::'? ADL是否會造成其他方面的干擾,還是僅僅是一種習慣?我會假設,當兩個重載都在同一個命名空間中時,這並不重要。 – TemplateRex

相關問題