我认为用于存储指针之间差异的正确类型是ptrdiff_t.
因此,我对我STL(msvc 2010)实现它的std::vector::size()功能的方式感到困惑.返回类型是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);
}
Run Code Online (Sandbox Code Playgroud)
很显然,有一个位的元魔,为了继续,以确定到底是什么类型的size_type和pointer是.为了"确定"它们是什么类型我检查了这个:
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*
Run Code Online (Sandbox Code Playgroud)
编译具有以下/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);
Run Code Online (Sandbox Code Playgroud)
改变的类型mysize2,以ptrdiff_t在没有任何警告的结果.改变的类型mysize1,以ptrdiff_t在结果unsigned-to-signed mismatch.
显然我错过了一些东西......
编辑:我不是问如何抑制警告,使用演员或者#pragma disable(xxx).我担心的问题是,size_t并ptrdiff_t可能有不同的允许范围(他们做我的机器上).
考虑std::vector<char>::max_size().我的实现返回max_size等于std::numeric_limits<size_t>::max().因为在投射之前vector::size()创建一个类型的中间值似乎在这里可能存在问题 - 不足以容纳.ptrdiff_tsize_tptrdiff_tvector<char>::max_size()
一般来说,ptrdiff_t是一个与size_t大小相同的有符号整数类型.它必须签名,以便它可以代表p1 - p2和p2 - p1.
在std :: vector内部的特定情况下,实现者实际上是size()从中派生出来的end() - begin().由于std :: vector(连续的,基于数组的存储)的保证,结束指针的值总是大于begin指针的值,因此不存在生成负值的风险.实际上,size_t总是能够表示比ptrdiff_t更大的正范围,因为它不必使用其一半的范围来表示负值.实际上,这意味着在这种情况下,从ptrdiff_t到size_t的强制转换是一个扩展的强制转换,它具有明确定义(并且直观明显)的结果.
另请注意,这不是std :: vector唯一可能的实现.它可以很容易地实现为单个指针和size_t值保持大小,派生end()为begin() + size().该实施也将解决您的max_size()担忧.实际上,max_size实际上永远不可能实现 - 它需要为程序的缓冲区分配程序的整个地址空间,不会给begin()/ end()指针,函数调用堆栈等留下空间.