2

I read in a tutorials said:

bool is_nonempty_notgood = (v.size() > 0); // Try to avoid this
bool is_nonempty_ok = !v.empty();

The explanation I failed to understand:

first, size() is unsigned, which may sometimes cause problems;

Second, it’s not a good practice to compare v.size() to zero if you want to know whether the container is empty.This is because not all the containers can report their size in O(1), and you definitely should not require counting all elements in a double-linked list just to ensure that it contains at least one.

Could someone provide some examples and more details?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Michael
  • 1,313
  • 11
  • 25
  • 3
    Because `(v.size() >= 0)` is a bug for checking for non empty container. – Alex Lop. Oct 08 '18 at 08:21
  • What is the source of the explanations you were given? – coredump Oct 08 '18 at 08:21
  • In most cases it's simply a readability issue. `v.empty()` is much easier to read and parse in your head than `v.size() == 0`. Also, as others noticed, `empty` is less error-prone than comparison (the mistake you made here). – Yksisarvinen Oct 08 '18 at 08:21
  • That has to be a typo. `size()` members of typical containers return unsigned values. Which means `v.size() >= 0` must *always* be true, so that's just a flat out bug. It can never be negative. A decent compiler will warn you as much. – WhozCraig Oct 08 '18 at 08:24
  • Its because of `is_nonempty = ( v.size() > 0 )` and it is not `(v.size() >= 0 )` – tunglt Oct 08 '18 at 08:28
  • 3
    There is a parcimony principle here: only ask for what you need (is the container empty), and not something possibly more difficult to compute (what is the size of the container). – coredump Oct 08 '18 at 08:28
  • 1
    That's a pointlessly technical explanation - `empty` should be preferred because it expresses *exactly* what the code is interested in. If you use `size`, you leave the reader to figure out whether the code really is interested in emptiness, or whether there's a bug. There's a problem with "empty" too, though, in that it can be a verb; it can be confusing that emptying a container doesn't do anything. – molbdnilo Oct 08 '18 at 08:53

2 Answers2

4
bool is_nonempty_notgood = (v.size() >= 0); // Try to avoid this

That should be a >, not a >=.

first, size() is unsigned, which may sometimes cause problems;

Sizes being unsigned or not is a recurrent topic in C/C++, see e.g. Why is size_t unsigned?

In general, unsigned integers have some pitfalls. If you don't want to deal with those, simply use signed integers (be it a size or not).

Second, it’s not a good practice to compare v.size() to zero if you want to know whether the container is empty.This is because not all the containers can report their size in O(1), and you definitely should not require counting all elements in a double-linked list just to ensure that it contains at least one.

Imagine I give you a deck. At a quick glance, you know there is at least one card in it (!v.empty()), right?

However, if I ask you to count exactly how many cards are there (v.size()), it will take you a while.

Acorn
  • 24,970
  • 5
  • 40
  • 69
1

For some containers, size() might be an O(N) traversal, whereas empty() is probably O(1). But do note that C++11 and onwards requires all standard containers' size() and empty() to be O(1).

So if you want to write container-agnostic code, then plump for empty() if you can.

Finally did you want size() > 0?

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • All **standard** containers have [O(1) complexity](https://stackoverflow.com/a/13751799/15416), since C++11. – MSalters Oct 08 '18 at 08:43