繁体   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