Beyond the Basics: Exploring Alternatives to std::basic_string_view::compare in C++


What is std::basic_string_view?

  • It doesn't own the underlying data but provides access to a portion of the characters.
  • Introduced in C++17, std::basic_string_view represents a lightweight view into an existing string.

What does compare do?

compare allows you to compare two sequences of characters. It takes several overloads to handle different comparison scenarios:

    • You can directly compare two std::basic_string_view objects.
    • The function compares the characters lexicographically (character by character).
  1. Comparing with a null-terminated string

    • You can compare a std::basic_string_view with a C-style null-terminated string (char array).
    • It compares characters up to the null terminator in the second string.
  2. Comparing a specific part of the string_view

    • You can specify a starting position (pos1) and a number of characters (count1) within the string_view to compare with another string/string_view.

Return value

  • The function returns an integer value indicating the comparison result:
    • Negative value: The string_view comes lexicographically before the other string.
    • Zero: The strings are equal.
    • Positive value: The string_view comes lexicographically after the other string.

Benefits of std::basic_string_view::compare

  • Flexible as it allows comparing substrings within the string_view.
  • Lightweight and efficient compared to full string copies for comparison.


Example 1: Simple string comparison

#include <iostream>
#include <string_view>

int main() {
  std::string_view str1 = "Apple";
  std::string_view str2 = "Banana";

  int comparison = str1.compare(str2);

  if (comparison < 0) {
    std::cout << str1 << " comes before " << str2 << std::endl;
  } else if (comparison == 0) {
    std::cout << str1 << " is equal to " << str2 << std::endl;
  } else {
    std::cout << str1 << " comes after " << str2 << std::endl;
  }

  return 0;
}

This code compares two string_view objects "Apple" and "Banana". The output will be:

Apple comes before Banana

Example 2: Comparing a substring

#include <iostream>
#include <string_view>

int main() {
  std::string str = "Programming";
  std::string_view str_view(str.data(), 5); // View of first 5 characters

  if (str_view.compare("Progr") == 0) {
    std::cout << "The first 5 characters of 'Programming' are 'Progr'" << std::endl;
  } else {
    std::cout << "Mismatch in substrings" << std::endl;
  }

  return 0;
}

Here, we create a string_view from the first 5 characters of "Programming". Then, we compare it with the string "Progr". The output will be:

The first 5 characters of 'Programming' are 'Progr'

Example 3: Comparing with a C-style string

#include <iostream>
#include <string_view>

int main() {
  std::string_view str_view = "Hello";
  const char* c_str = "World";

  if (str_view.compare(c_str) < 0) {
    std::cout << str_view << " comes before " << c_str << std::endl;
  } else {
    std::cout << str_view << " is not lexicographically before " << c_str << std::endl;
  }

  return 0;
}

This code compares a string_view "Hello" with a C-style string "World". The output will be:

Hello comes before World


    • You can use the relational operators (==, !=, <, >, <=, >=) to compare two std::string objects directly.
    • These operators are convenient for simple comparisons but provide less flexibility compared to compare.
    #include <iostream>
    #include <string>
    
    int main() {
      std::string str1 = "Apple";
      std::string str2 = "Banana";
    
      if (str1 == str2) {
        std::cout << str1 << " is equal to " << str2 << std::endl;
      } else {
        std::cout << str1 << " is not equal to " << str2 << std::endl;
      }
    
      return 0;
    }
    
  1. strcmp (C-style strings)

    • The strcmp function from the C library (declared in <cstring>) compares null-terminated character arrays (C-style strings).
    • It returns an integer similar to compare:
      • Negative: First string comes before the second.
      • Zero: Strings are equal.
      • Positive: First string comes after the second.

    Caution
    Be mindful of potential buffer overflows when using strcmp as it doesn't perform bound checking.

    #include <iostream>
    #include <cstring>
    
    int main() {
      const char* str1 = "Apple";
      const char* str2 = "Banana";
    
      int comparison = strcmp(str1, str2);
    
      if (comparison < 0) {
        std::cout << str1 << " comes before " << str2 << std::endl;
      } else if (comparison == 0) {
        std::cout << str1 << " is equal to " << str2 << std::endl;
      } else {
        std::cout << str1 << " comes after " << str2 << std::endl;
      }
    
      return 0;
    }
    
  2. Custom comparison functions

    • You can write your own comparison functions to define specific logic for comparing strings.
    • This might be useful for case-insensitive comparisons, comparisons based on specific delimiters, etc.

Choosing the best alternative depends on your specific needs and the context of your code.

  • For complex comparison logic, a custom function might be necessary.
  • If you need more flexibility or are working with C-style strings, std::basic_string_view::compare or strcmp can be appropriate (with caution for strcmp).
  • If you're dealing with std::string objects and want a simple comparison, relational operators are a good choice.