0

From this code:

#include <iostream>
#include <typeinfo>
#include <string>

int main() {
    std::string const s = "Thisisastring";
    std::string const ss = "Thisisastringg";
    std::string const sss = "Thisisastrin";
    auto p = ss.find(s);
    std::cout << "p:" << typeid(p).name() << "\np =" << p << std::endl;
    auto pp = sss.find(s);
    std::cout << "pp:" << typeid(pp).name() << "\npp =" << pp << std::endl;
    return 0;
}

I get the following output:

p:m
p =0
pp:m
pp =18446744073709551615

Questions:

  • From this link, p should have the type size_type against m?

  • What does the value of pp means? An overflow?

Frank Wang
  • 788
  • 7
  • 23

2 Answers2

4

The value of pp equal to string::npos (2^64-1 = 18446744073709551615). That is, the string is not found, not an overflow.

The string.find(...) method returns any of the followings

  1. If the string is matched, it return the position of the first character of the first match.
  2. If no matches were found, it returns string::npos

where npos is a static member constant value with the greatest possible value for an element of type size_t (an unsigned integral type).

To verify it print the string::npos

std::cout << std::string::npos << std::endl;
1

size_type is not a type by itself, it is an alias defined as follow:

typedef Allocator::size_type size_type; // until c++11
typedef std::allocator_traits<Allocator>::size_type size_type; // since c++11

Since you are using std::string, the allocator is std::allocator<char> and thus size_type is std::size_t.

The return value of std::type_info::name is implementation defined, and m is what your compiler (presumably g++) chose to use for std::size_t.

The return value of std::basic_string::find when the substring is not found is std::basic_string::npos, which is defined as:

static const size_type npos = -1;

In your case, it comes down to:

static const std::size_t npos = -1;
// which is (due to arithmetic modulo 2^n):
static const std::size_t npos = std::numeric_limits<std::size_t>::max();

And with your compiler, the resulting value is 18446744073709551615 which is 2^64 - 1 because std::size_t is probably a 64-bits value on your computer. This is a possible value, std::size_t is not required to be 64-bits long.

You should always test the return value of std::basic_string::find (and other related functions) against std::basic_string::npos directly.

Holt
  • 36,600
  • 7
  • 92
  • 139
  • Ummm, `size_t` is required to be an unsigned integral type, and unsigned integral types follow the rules of modular arithmetic. The only thing that can vary is the number of bits. – Ben Voigt Jun 20 '16 at 06:59