Component of the Week #6: bdlb_transparent*

Summary:
  • Provide comparators and hash functions for use with standard containers that allow users to efficiently search the container using a type different from (but comparable to) the container’s key.

It is often desired to have an ability to search for elements in an associative container using a key type that is different from the container’s key type, but still comparable. The C++ standard associative containers support such a search (sometimes described as a “heterogenous lookup”) by way of what the standard describes as “transparent” comparators. The bdlb_transparent* components are collection of those “transparent” comparators.

Let’s look at a standard use of a bsl::set containing a set of strings. We will populate the container with a few values and then try some lookups using different string-like keys:

bsl::set<bsl::string> mySet;
mySet.insert("apple")
mySet.insert("peach");

if (mySet.contains("apple")) {       // Implicit conversion to bsl::string!
    bsl::cout << "Found 'apple'\n";
}

bsl::string_view apple = "apple";
if (mySet.contains(apple)) {         // Error ???
    bsl::cout << "Found 'apple'\n";
}

and, while one would expect this code to work, the first call does a fairly expensive implicit conversion, and the second call does not even compile!

This is where a transparent comparator comes to the rescue. By specializing the bsl::set with the bdlb::TransparentLess comparator, we unlock the ability to search the container with types comparable with bsl::string:

bsl::set<bsl::string, bdlb::TransparentLess> mySet;
...

if (mySet.contains("apple")) {
    bsl::cout << "Found 'apple'\n";
}

bsl::string_view apple = "apple";
if (mySet.contains(apple)) {
    bsl::cout << "Found 'apple'\n";
}

Also note that transparent comparator also eliminates the implicit conversion for the call with const char*.

For heterogeneous lookups in unordered associative containers, the bdlb package provides transparent equality (bdlb::TransparentEqualTo) and hashing (bdlb::TransparentHash and bdlb::TransparentStringHash) functors.

Note that bdlb::TransparentStringHash should be used for hashing string-like types as it implements correct hashing for char * ( i.e., it will return the same hash for bsl::string, bsl::string_view, [const] char *, and (deprecated) bslstl::StringRef objects having the same literal value).

Check out the full documentation for

Happy coding!