39

何かをデバッグしているときに、STL の vector::empty() 実装を見ました。

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

vector の空を調べるときはいつでも、size() よりも empty を使用することをお勧めします。しかし、その実装を見て、そうする利点は何だろうと思います。代わりに、内部的に size()==0 を呼び出すため、empty の呼び出しには関数呼び出しのオーバーヘッドがあります。

size() はリスト内の一定の時間を保証しないため、リストの場合は empty() が役立つかもしれないと思いました。私の仮定を確認するために、リストの実装を確認したところ、驚くべきことに、リストにも同じ実装が見つかりました。

return (size() == 0);

私は今少し混乱しています。empty が内部で size() を使用している場合、なぜ size() よりも empty を優先する必要があるのでしょうか?

4

9 に答える 9

45

std::vector から std::list または他のコンテナーに切り替えると、異なる場合があるためです。

たとえば、std::list::sizetakeO(n)と notのいくつかの実装O(1)

于 2009-04-13T06:41:20.907 に答える
11

まあ、あなたが言うように、それは単なる実装の詳細です。std::list格納されたサイズ (constant-time size()but linear-time splice()) またはなし (constant-time splice()but linear-time size()) のいずれかで実装できます。を使用することを選択するとempty()、サイズを知る必要がない場合に、実装の詳細に賭ける必要がなくなります。

于 2009-04-13T06:42:36.270 に答える
7

empty()まず、何かが空かどうかを知りたいときに呼び出される関数を使用すると、コードが読みやすくなり、実装の詳細について心配する必要がなくなります。また、他の特性を持つ他のタイプのコンテナーにコードをより簡単に適応させることができることも意味します。

第 2 に、これは 1 つの STL 実装にすぎません。私の GNU C++ は次のようになります。

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

これは最終的にポインタ比較になりますが、size() を使用すると減算になります (この実装では)。

empty()第 3 に、 (両方の実装で) -function はおそらくインライン化されているため、追加の関数呼び出しのオーバーヘッドが発生する可能性はほとんどありません。

于 2009-04-13T09:03:32.127 に答える
5

empty() には、すべてのコンテナ クラスの O(1) 実装があります。size() は、一部のコンテナーに対して O(n) 実装のみを提供できます。これが empty() が好まれる理由です。

于 2009-04-14T03:05:45.377 に答える
1

上記の理由に加えて、おそらく foo.size() == 0 や !foo.size() よりも明確です。

于 2009-04-13T07:38:09.867 に答える
0

非常に有効な可読性の点に加えて、経験したことは単に特定の実装の成果物であり、可能な唯一のものではありません。

つまり、vector と list の両方のケースで、または実際に他のコンテナーで size() に関して empty() を実装する理由や要件はありません。ライブラリの作成者が無能であるか、より合理的に怠け者でない限り、より優れたパフォーマンスの代替手段がある場合は、それらを使用する必要があります。

list と size() の O(1) 性、またはその欠如については、list が size() を O(1) または splice() として実装する可能性があることを考慮する必要がありますが、両方を実装することはできません (考えて理由については興味深い演習です。) したがって、あなたの場合、検査したライブラリは size() を O(1) として実装している可能性があります (この場合、 splice() は O(n) になります)。したがって、 empty() を実装できます。パフォーマンスを犠牲にすることなく size() に関して、そうでなければ、それは本当に悪いライブラリになります。

于 2009-04-13T13:57:34.587 に答える