size()' 作業順序

常數順序與線性順序 size()

std:: 容器不同,並非所有 fbl:: 容器都會自動追蹤容器的特定大小。具體來說,關聯容器一律會追蹤容器中的元素數量,但排序容器預設不會追蹤。

為避免任何意外情況 (例如,在容器上對 size() 方法發出非預期的 O(n) 呼叫) 時,序列容器的 API 不會包含 size() 方法。更準確地,嘗試呼叫 size() 將觸發 static_assert 並無法編譯。

相反地,如果必須知道序列容器中目前的特定元素數量,且元素的 O(n) 數量是可接受的付費價格,則可改為呼叫 size_slow()

另一方面,如果序列容器中需要 O(1) 效能,使用者可能會改用容器的「大小」版本。容器的記憶體內大小會增加一個 size_t,而在容器間新增/移除元素,也會稍微增加維護容器中元素數量的成本。現在可以呼叫 size(),且呼叫 size_slow() 會發生錯誤。

如要指定清單應自動追蹤其大小,最簡單的方法是在宣告容器時使用 SizedSinglyLinkedListSizedDoublyLinkedList 範本別名。或者,您也可以手動指定範本引數,方法是將 fbl::SizeOrder::Constant 或 fbl::SizeOrder::N 傳送至範本引數中的適當位置。

所有 fbl:: 容器都支援價格低廉的 O(1) is_empty() 作業,可用於測試容器是否包含「任何」元素。

// This is a list with an O(n) size_slow method
fbl::SinglyLinkedList<std::unique_ptr<Obj>> my_stack;
if (my_stack.size() > 50) { /* ... */ }       // not allowed. Compile time error
if (my_stack.size_slow() > 50) { /* ... */ }  // allowed.
if (my_stack.is_empty()) { /* ... */ }        // always allowed.

// This is a list with an O(1) size method
fbl::SizedSinglyLinkedList<std::unique_ptr<Obj>> my_sized_stack;
if (my_sized_stack.size() > 50) { /* ... */ }      // allowed.
if (my_sized_stack.size_slow() > 50) { /* ... */ } // not allowed. Compile time error
if (my_sized_stack.is_empty()) { /* ... */ }       // always allowed.

// A more verbose way to say the same thing
fbl::SinglyLinkedList<std::unique_ptr<Obj>,
                      fbl::DefaultObjectTag,
                      fbl::SizeOrder::Constant> another_sized_stack;
if (another_sized_stack.size() > 50) { /* ... */ }      // allowed.
if (another_sized_stack.size_slow() > 50) { /* ... */ } // not allowed. Compile time error
if (another_sized_stack.is_empty()) { /* ... */ }       // always allowed.

// Both of these work as well.
struct Tag1 {};
struct Tag2 {};
fbl::SinglyLinkedList<std::unique_ptr<Obj>, Tag1,
                      fbl::SizeOrder::Constant> t1_sized_stack;
fbl::TaggedSinglyLinkedList<std::unique_ptr<Obj>, Tag2,
                      fbl::SizeOrder::Constant> t2_sized_stack;
if (t1_sized_stack.size() > 50) { /* ... */ }      // allowed.
if (t2_sized_stack.size() > 50) { /* ... */ }      // allowed.
if (t1_sized_stack.size_slow() > 50) { /* ... */ } // not allowed. Compile time error
if (t2_sized_stack.size_slow() > 50) { /* ... */ } // not allowed. Compile time error