I think the [answer of rwong above][1] already excellently highlights the issues.

I'll add what think are worth mentioning:

* `size_t`, that is a size that covers the *full* available flat memory range of the C++ abstract machine is only required for range indices when `sizeof(type)==1`, that is, if you're dealing with byte (`char`) types.
* As such, `xxx::size_type` could be used in 99.9% cases even if it were a signed machine word sized type.
* The fact that `std::vector` and friends chose `size_t`, an **unsigned** type, for the size and indexing is [considered by some][2] to be a design flaw. I concur. (Seriously, take 5 minutes and watch the [lightning talk CppCon 2016: Jon Kalb “unsigned: A Guideline for Better Code"][2].)
* When you design an C++ API today, you're in a tight place: Use `size_t` to be consistent with the Standard Library, or use (the *signed*)  **`intptr_t`** for easy and less bug prone indexing calculations.
* Don't use int32 or int64 - use `intptr_t` if you want to go signed, and want machine word size.

To directly answer the question, it is not entirely an "historical artefact", as the theoretical issue of needing to address more than half the address space *must* be, aehm, addressed somehow in a low level language like C++.

In hindsight, I, *personally*, think, it **is** a design flaw that the Standard Library uses unsigned `size_t` all over the place even where it does not represent a raw memory size, but a capacity of typed data, like for the collections:

* *given C++s integer promotion rules* ->
* unsigned types just don't make good candidates for "semantic" types for something like a size that is semantically unsigned.

I'll repeat [Jon's advice][3] here:

* Select types for the operations they support (not the range of values). (*1)
* Don't use unsigned types in you API. This hides bugs with no upside benefit.
* Don't use "unsigned" for quantities.(*2)

(*1) i.e. unsigned == bitmask, never do math on it (here hits the first exception - you may need a counter that wraps - this must be an unsigned type.)

(*2) quantities meaning something you count and/or do math on.


  [1]: http://softwareengineering.stackexchange.com/a/338107/6559
  [2]: https://www.youtube.com/watch?v=wvtFGa6XJDU
  [3]: https://youtu.be/wvtFGa6XJDU?t=358