size()与向量中的空() - 为什么首选empty()?

aJ.*_*aJ. 32 c++ size stl

在调试时,我看到了STL vector :: empty()实现:

bool empty() const
        {return (size() == 0); }
Run Code Online (Sandbox Code Playgroud)

我相信,每当我们探测向量的空虚时,总是建议使用空的大小().但是看到这个实现,我想知道,这样做有什么好处?相反,在调用empty时会有一个函数调用开销,因为它在内部调用size()== 0.

我认为在列表的情况下empty()可能会有用,因为size()不保证列表中的常量时间.为了验证我的假设,我检查了列表实现,令人惊讶的是,在列表中也找到了相同的实现,

return (size() == 0);
Run Code Online (Sandbox Code Playgroud)

我现在有点困惑.如果empty在内部使用size()那么我们为什么要选择empty over size()?

Art*_*yom 43

因为如果从std :: vector切换到std :: list或其他容器,它可能会有所不同.

例如,std::list::sizetake O(n)和not的一些实现O(1).

  • 这个答案在C++ 03中是正确的.在C++ 11中,`size`必须是恒定的时间. (9认同)

dir*_*tly 26

每次使用时都需要写出条件size().使用方便empty().这当然是,如果你不切换容器.正如其他人所指出的那样,它是高达执行使用size()empty()或没有.但是,该标准确保:empty()对所有标准容器都是恒定时间操作.


Chr*_*ung 10

好吧,正如你所说,这只是一个实现细节.std::list可以使用存储的大小(恒定时间size()但线性时间splice())或不使用(恒定时间splice()但线性时间size())来实现.通过选择使用empty(),当您不需要知道大小时,可以避免押注实施细节.


Dav*_*eas 6

遵循标准,应该首选empty(),因为无论容器类型如何,它都具有恒定的时间复杂度.

在C++ 03标准中,第23.1章,表65:容器要求

Operation:   empty()
Return_type: convertible to bool
Semantics:   equivalent to size()==0
Complexity:  constant
Run Code Online (Sandbox Code Playgroud)

似乎在您的STL实现中,它们将语义作为忽略复杂性要求的实际实现,或者size()是实现中的常量时间(存储字段).

如果size()不是常量时间,请联系您的供应商,了解std :: list <> :: empty()不符合标准容器要求.


gnu*_*nud 5

1,使用empty()当你想知道某些东西是否为空时调用的函数使代码更具可读性,这意味着你不必担心实现细节.这也意味着您的代码可以更容易地适应其他类型的容器,具有其他特征.

2,这只是一个STL实现.我的GNU C++看起来像这样:

bool
empty() const
{ return begin() == end(); }
Run Code Online (Sandbox Code Playgroud)

这最终将导致指针比较,而使用size()将导致减法(在此实现中).

第三,它不太可能产生额外函数调用的开销,因为empty()函数可能是内联的(在两个实现中).


pax*_*977 5

empty() 对所有容器类都有 O(1) 实现。size() 只能为某些容器提供 O(n) 的实现;这就是为什么 empty() 是首选。