Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Are two std::string_views refering to equal-comparing string literal always also equal?

I have an unordered_map which is supposed to mimic a filter, taking key and value as std::string_view respectively. Now say I want to compare two filters that have the same key-value-pairs: Will they always compare equal?

My thought is the following: The compiler tries its best to merge const char*’s with the same byte information into one place in the binary, therefore within a specific translation unit, the string literal addresses will always match. Later I’m passing these addresses into the constructor of std::string_view. Naturally, as std::string_view doesn’t implement the comparison operator==(), the compyler will byte-compare the classes and only when address and length match exactly, the std::string_views compare equal.

However: What happens if I instantiate a filter outside of this translation unit with exactly the same contents as the first filter and link the files together later? Will the compiler be able to see beyond the TU boundaries and merge the string literal locations as well? Or will the equal comparison fail as the underlying string views will have different addresses for their respective string literals?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Demo

#include <unordered_map>
#include <string_view>
#include <cstdio>


using filter_t = std::unordered_map<std::string_view, std::string_view>;

int main()
{
    filter_t myfilter = {{ "key1", "value"}, {"key2", "value2" }};

    filter_t my_second_filter = {{ "key1", "value"}, {"key2", "value2" }};

    if (my_second_filter == myfilter) {
        printf("filters are the same!\n");
    }
}

>Solution :

Naturally, as std::string_view doesn’t implement the comparison operator==(), the compyler will byte-compare the classes

That is never the case. If no operator== overload (or since C++20 a rewritten candidate overload of e.g. operator<=>) is available for a class type, then it is simply impossible to compare the type with ==.

Even for non-class types the built-in == never performs a bitwise/bytewise comparison of the object representation (i.e. the values of the bytes of storage occupied the object). The built-in == always performs a comparison of values held by the objects.

The only way to get bytewise comparison of the object representation is to explicitly have a operator== (or overload to which == can be rewritten) be defined to perform this comparison (e.g. by memcmp). Since that obviously wouldn’t make sense for std::string_view (or most types), the standard library does not define std::string_view‘s operator== like that. It defines operator== (or operator<=> since C++20) instead to properly perform a comparison of the string it refers to, as a value, not as identity of a string literal or character array, see https://en.cppreference.com/w/cpp/string/basic_string_view/operator_cmp.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading