size() 的操作顺序

常量顺序与线性顺序(size()

std:: 容器不同,并非所有 fbl:: 容器都会自动跟踪 容器的大小具体来说,关联容器始终 跟踪容器中元素的数量,而按顺序排列的容器则 而不是默认情况下

为了避免意外操作, 对容器上的 size() 方法进行意外的 O(n) 调用, 有序容器不包含 size() 方法。更多 因此,尝试调用 size() 将会触发 static_assert,并且无法 编译。

相反,如果当前按顺序排列的容器中的元素数量 元素数量的 O(n) 才是可接受的价格 pay,可能会改为调用 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