簡體   English   中英

size_t、ptrdiff_t 和 std::vector::size()

[英]size_t, ptrdiff_t and std::vector::size()

我認為用於存儲指針之間差異的正確類型是ptrdiff_t

因此,我對我的STL (msvc 2010)實現它的std::vector::size() function 的方式感到困惑。 返回類型是size_t (據我所知,這是標准規定的),但它被計算為指針的差異:

// _Mylast, _Myfirst are of type pointer
// size_type, pointer are inherited from allocator<_Ty>
size_type size() const 
{
    return (this->_Mylast - this->_Myfirst);
}

顯然,為了准確地確定size_typepointer是什么類型,需要使用一些元魔法。 為了“確定”它們是什么類型,我檢查了這個:

bool bs = std::is_same<size_t, std::vector<int>::size_type>::value;
bool bp = std::is_same<int * , std::vector<int>::pointer>::value;
// both bs and bp evaluate as true, therefore:
//   size_type is just size_t
//   pointer is just int*

/Wall編譯以下內容會給我一個有signed-to-unsigned mismatch mysize2 ,但沒有警告mysize1

std::vector<int> myvector(100);
int *tail = &myvector[99];
int *head = &myvector[ 0];
size_t mysize1 = myvector.size();
size_t mysize2 = (tail - head + 1);

mysize2的類型更改為ptrdiff_t不會導致警告。 mysize1的類型更改為ptrdiff_t會導致unsigned-to-signed mismatch

顯然我錯過了一些東西......

編輯:我不是在問如何使用強制轉換或#pragma disable(xxx)來抑制警告。 我擔心的問題是size_tptrdiff_t可能有不同的允許范圍(它們在我的機器上)。

考慮std::vector<char>::max_size() 我的實現返回一個等於std::numeric_limits<size_t>::max()max_size 由於vector::size()在轉換為size_t之前創建了ptrdiff_t類型的中間值,因此這里似乎可能存在問題 - ptrdiff_t不足以容納vector<char>::max_size()

一般來說,ptrdiff_t 是一個與 size_t 大小相同的有符號整數類型。 它必須經過簽名,以便它可以代表p1 - p2p2 - p1

在 std::vector 內部的特定情況下,實現者有效地從end() - begin()派生size() ) 。 由於 std::vector (連續的,基於數組的存儲)的保證,結束指針的值將始終大於開始指針的值,因此不存在產生負值的風險。 事實上,size_t 總是能夠表示比 ptrdiff_t 更大的正范圍,因為它不必使用其范圍的一半來表示負值。 實際上,這意味着在這種情況下,從 ptrdiff_t 到 size_t 的轉換是一個擴大的轉換,它具有明確定義(並且直觀地明顯)的結果。

另外,請注意這不是 std::vector 的唯一可能實現。 它可以很容易地實現為單個指針和一個保存大小的 size_t 值,將end()派生為begin() + size() 該實現還將解決您的max_size()問題。 實際上,max_size 永遠無法實現——它需要為向量的緩沖區分配程序的整個地址空間,沒有空間給 begin()/end() 指針、function 調用堆棧等。

在 STL 中如何實現 std::vector::size() 並沒有錯。 this->_Mylast - this->_Myfirst == 向量大小只是一個巧合的事實,它依賴於向量的實現方式。

加上 MSVC STL 向量實現有一個#pragma warning(disable: 4244)刪除警告。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM