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

时间:2009-04-13 06:38:14

标签: c++ stl size

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

bool empty() const
        {return (size() == 0); }

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

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

return (size() == 0);

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

9 个答案:

答案 0 :(得分:43)

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

例如std::list::size的某些实现采用O(n)而非O(1)

答案 1 :(得分:25)

每次使用size()时,您都需要写出条件。使用empty()很方便。这当然是,如果你不切换容器。正如其他人所指出的那样,在size()中使用empty()是否可以实现。但是,该标准确保:empty()是所有人的固定时间操作 标准容器。

答案 2 :(得分:10)

好吧,正如你所说,这只是一个实现细节。 std::list可以使用存储的大小(常量size()但线性时间splice())或不使用(常量splice()但线性时间{{}来实现1}})。选择使用size()时,如果您不需要知道尺寸,就可以避免投注实施细节。

答案 3 :(得分:6)

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

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

Operation:   empty()
Return_type: convertible to bool
Semantics:   equivalent to size()==0
Complexity:  constant

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

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

答案 4 :(得分:5)

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

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

bool
empty() const
{ return begin() == end(); }

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

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

答案 5 :(得分:4)

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

答案 6 :(得分:1)

除了上面给出的理由之外,它还可以说比foo.size()== 0和/或!foo.size()

更清晰

答案 7 :(得分:0)

除了可读性点,这是非常有效的,你所经历的只是一个特定实现的工件,而不是唯一可能的实现。

也就是说,没有理由或要求在vector和list case中或者在任何其他容器中使用size()实现empty()。如果有更好的替代方案,应该使用它们,除非图书馆的作者不称职,或者更合理,懒惰。

对于列表和O(1) - size()的性质,或缺少它,你应该考虑到列表可以实现size()为O(1)或splice(),但不是两者(考虑原因是一个有趣的练习。)所以在你的情况下,你检查的库可能已经实现了size()为O(1)(在这种情况下splice()将是O(n))因此可以实现在大小()方面的empty()而不牺牲性能,否则,这将是一个非常糟糕的库。

答案 8 :(得分:0)

首选使用empty()而不是size(),因为每个容器可能以不同的方式实现empty()实现以获得常量时间操作。

示例:

vector实现为:             bool empty()const         {//测试序列是否为空         return(size()== 0);         }

list实现为:

        bool empty() const
    {   // test if sequence is empty
    return (_Mysize == 0);
    }