Question: Currently I have a scenario where I want to check whether writing a given string to a filestream will grow the file beyond a given size (this is used for logfile rotation). Now, `std::ofstream::tellp()` returns a `streampos`, but `std::string::size()` returns a `size_t`. The effect is, that this does not work:

```
out_stream.tellp() + string.size() < limit

```

because apparently there is an ambiguous overload of `operator +` for these types. This leads me to two questions:

1. How can I resolve the above ambiguity?
2. How do all the different types (`size_t`, `streamsize`, `streampos`, `streamoff`) relate to each other? When can they be safely converted, and what are possible pitfalls. I am generally confused about these types. All I know is that they are implementation dependent, and that they make certain guarantees (e.g. `size_t` is always large enough to hold the size of the larges object that would fit into memory on the architecture for which the application was compiled), but what are the guarantees concerning interoperability of these types (see example above, or comparing a `streamsize` to a `size_t`)?

Answer: 
You should be able to convert the result from tellp to a `std::string::size_type` by casting.

`static_cast<std::string::size_type>(out_stream.tellp()) + string.size() < limit`

EDIT: This is safe because your stream offset will never be negative and will safely convert to an unsigned value.
The real question is: what is the type of limit? The usual way of
testing if there is still room is usually:
 limit - out\_stream.tellp() >= string.size()
But you have to ensure that limit has a type from which
out\_stream.tellp() can be subtracted. 

In theory, streampos isn't convertable nor comparable to an integral
type, or that, converted to an integral type, it gives significant
information. And it needed support subtraction, or comparison, for that
matter. In practice, I don't think you have to worry too much about the
conversion to an integral type existing, and being monotonic (although
perhaps on some exotic mainframe...). But you can't be sure that
arithmetic with it will work, so I'd probably prefer converting it
explicitly to a streamsize (which is guaranteed to be a signed integral
type). (Regardless of how you approach the problem, you'll have to deal
with the fact that string.size() returns a size\_t, which is required to
be unsigned, whereas streamsize is required to be signed.)

With regards to your second question:
 size\_t is a typedef to an unsigned integral type, large enough to
 specify the size of any possible object,
 streamsize is a typedef to a signed integral type, large enough to
 specify the size of an "object" in a stream,
 streamoff is a typedef to an integral type capable of specifying
 the position of a byte in a file, and 
 streampos is a typedef to fpos, where
 something is a type which can be used to maintain the state in
 the case of a multibyte stream.
The standard makes very few requirements concerning the relationships
between them (and some of the few it makes are mathematically impossible
to realize), so you're pretty much on your own.