string_viewoperator+ vs. StrCat()absl::Statusstd::bindabsl::optional and std::unique_ptrabsl::StrFormat()make_unique and private Constructors.boolexplicit= delete)switch Statements Responsibly= deleteAbslHashValue and Youcontains()std::optional parametersif and switch statements with initializersinline Variablesstd::unique_ptr Must Be MovedAbslStringify()vector.at()auto for Variable Declarationscontains()Originally posted as TotW #158 on January 3, 2019
Updated 2020-04-20
Quicklink: abseil.io/tips/158
“I cannot contain myself” – Bertrand Russell
When checking whether a set contains a value or a map contains a key, C++ has historically forced users to choose between writing the rather verbose
container.find(value) != container.end()
or the arguably obtuse (and sometimes inefficient)
container.count(value) != 0
instead of writing
container.contains(value)
as we’d like to.
container.contains(value) to the RescueThe simpler syntax is part of the C++20 Standard, and Abseil’s
(absl::{flat,node}_hash_{map,set}) and
btree containers (absl::btree_*) support it today.
contains has the same support for heterogeneous lookup as find,
so (for example) it’s possible to check whether an
absl::flat_hash_set<std::string> contains an absl::string_view value without
paying the costs of converting to a std::string object:
constexpr absl::string_view name = "Willard Van Orman Quine";
absl::flat_hash_set<std::string> names = {std::string(name)};
assert(names.contains(name)); // No dynamic allocation here.
Given that most of our code that needs associative containers (whether sets or maps) should be using the Abseil hashed containers today (see Tip #136), it should rarely be necessary to use one of the other formulations in new code.
NOTE: As described in Tip #132 (“Avoid Redundant Map Lookups”),
don’t check if an item is in a container and then do another operation that
implies a lookup (such as find, insert or remove).
Querying whether an item can be found in an associative container is a common
operation, and a natural syntax for it is container.contains(value). Prefer
that syntax when possible.