C++中string.size()的类型是什么?

Fel*_*elB -4 c++ string

我有以下代码:

#include<iostream>
#include<string>   
int main()
    {
        std::string s = "458";
        std::cout <<s.size()-4;
    }
Run Code Online (Sandbox Code Playgroud)

当我运行这个时,我得到42944935或类似的东西.但是当我通过以下修改运行它时:

int main()
{
    std::string s = "458";
    int i = s.size();
    std::cout << i -4;
}
Run Code Online (Sandbox Code Playgroud)

我得到-1,这是我从第一个代码中得到的.有人能解释一下这里发生了什么吗?

Che*_*Alf 9

由于历史原因,返回类型为std::string::size()is size_t,这是一个足以满足最大可能数组大小的无符号类型.

你可以通过定义一些通用的大小/长度函数来解决这个问题

using Size = ptrdiff_t;  // signed type

template< class Collection >
constexpr auto n_items( Collection const& c )
    -> Size
{ return c.size(); }

// Raw array. Using size_t template param for g++ compatibility.
template< class Item, size_t n >
constexpr auto n_items( Item (&)[n] )
    -> Size
{ return n; }
Run Code Online (Sandbox Code Playgroud)

在这里,我使用了这个名称,n_items因为C++ 17将定义一个通用size函数,不幸的是,它返回size_t(并且混合了许多大小的概念,也是不幸的).人们不希望那里发生名称冲突.


当你没有提供这些功能的另一种方法是表达大小的差异std::endstd::begin,如end(s) - begin(s).原始指针的差异类型是ptrdiff_t(已签名),并且您获取的迭代器的默认差异类型std::string::begin()ptrdiff_t来自std::iterator_traits.

  • 不仅是我会争辩的历史原因.将大小设置为无符号类型更有意义.大小或长度实际上不是负数. (7认同)
  • @JoachimPileborg:在SO,clc ++ m(存档)和其他地方的很多地方都讨论过.简而言之,它没有意义:它只是一个联想,就像大多数羊是白色的,大多数加工大米也是如此,因此大米属于绵羊(不是).计算优点和缺点,第一个和后者中有0个,特别是*modern*促销规则将隐式转换为无符号类型,一个错误的吸引器.比如,`std :: string("Hello").length()< - 5`保证保持不变.但这是胡说八道,一个错误. (4认同)
  • @JoachimPileborg由于历史原因,至少Carruth和Sutter对此表示遗憾(https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything 1:02:50;其他包括Stroustrup在9:50,42:40,他在同一个视频中反对未签名者,但这并不是特别谈论标准库.因此无论签署与未签署的讨论中的立场如何,"历史原因"部分可能是正确的. (4认同)
  • @BaummitAugen:我可能错了,但我相信没有自定义分配器的`std :: string`从`std :: allocator`得到它的大小类型,它是`size_t`. (2认同)