Effective STL Terms 4

zhaozj2021-02-11  181

Terms 4: Use EMPTY () instead of check size () is 0

For any container C, write down

IF (c.size () == 0) ...

Essentially equivalent to write

IF (c.empty ()) ...

This is example. You may be strange why a constructor is better than another, especially the typical implementation of EMPTY () is an inline function that returns size () whether it returns 0.

You should prefer EMPTY () construction, and reason is simple: for all standard containers, EMPTY () is a constant time operation, but for some List implementations, size () spends linear time.

But what causes List so trouble? Why can't you also provide a constant time size ()? The answer is something that has a lot of splice () for List. Consider this code:

List list1;

List list2;

...

List1.splice (// 把 中 中

List1.end (), list2, // From the first time

Find (list2.begin (), list2.end (), 5), // last appeared 10

Find (List2.rbegin (), List2.Rend (), 10). The part of the () // moves to the end of LIST1.

); / / About call

// "Base ()" information, see Terms 28

Unless the List2 has a 10 behind 5, this code cannot work, but we assume that this is not a problem. Instead, we pay attention to this problem: how many elements are LIST1 after merge? Obviously, the number of elements of the LIST1 after the merger is equal to the number of elements of the LIST1 before the merger. But how many elements merge it? That is equal to the number of elements defined by Find (List2.begin (), List2.end (), 5), and Find (List2.rbegin (), List2.Rend (), 10) .BASE (). OK, how much? Unrecognizable before the interval is not traversed and count. That is the problem.

Suppose you are responsible for implementing list, list is not just a normal container, which is a standard container, so you know that your class will be widely used. You naturally hope that your achievements are more efficient. You point out that customers often want to know how many elements in LIST, so you use size () to make a constant time. So you have to design the List to always know how much elements are included.

At the same time, you know that only the List provides the ability to merge the elements from one place to another without copying data. Your presentation is that many List users choose List because it provides an efficient merge. They know that from a list to a region to another List can be completed in a constant time, and you know that they understand this, so you know that you need to meet their expectations, that is, the merge is a constant time member function.

This makes you advance from two difficulties. If size () is a constant time operation, each List member function must update the size of the list when operating. Splice () is also included. However, let splice () updates the only way that the size of the LIST he change is to calculate the number of components that merge, but this will make splice () can't have the performance of the constant time you want. If you remove splice () to update the size of the size of the List he modified, splice () can be a constant time, but size () turns into linear time. In general, it must traverse its entire data structure to know how many elements are included. No matter how you look at it, some things --SE () or splice () must be concession. One or the other can be a constant time operation, but it cannot be all.

Different List implementations solve this contradiction in different ways, depending on their author chooses to achieve max () or splice () to the highest efficiency. If you happen to use a constant time SPLICE () than the constant time size () priority LIST implementation, call EMPTY () is better than calling size () because EMPTY () is always constant time operation. Even if you don't use this now, you may find that you will use it in the future. For example, you may put your code to a different platform for different STL implementations, you may just decide to switch to a different STL implementation on your current platform.

No matter what happens, if you use Empty () instead of checking size () is 0, you will not have something wrong. So when you want to know if the container contains 0 elements, EMPTY () should be called.

转载请注明原文地址:https://www.9cbs.com/read-4784.html

New Post(0)