The title is relatively self explanatory. I recognize the similarity to other answers, but all of those have different arrangements of operators (and therefore different casting rules). So I require an answer that clarifies this particular case.
If someone could point out the section of the standard that explains this, I will gladly vote up and accept the answer.
NO, it is not always true. It is however a bit more complicated than it seems at first glance:
In the beginning, let us see what std::string
is (21.3/1):
The header
<string>
defines thebasic_string
class template for manipulating varying-length sequences of char-like objects and four typedefs,string
,u16string
,u32string
, andwstring
, that name the specializationsbasic_string<char>
,basic_string<char16_t>
,basic_string<char32_t>
, andbasic_string<wchar_t>
, respectively.
Start out with 21.4/5:
template<class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> >
class basic_string {
typedef typename allocator_traits<Allocator>::size_type size_type;
static const size_type npos = -1;
// [other members omitted]
};
Note that while npos
is initialized with -1
, its type depends on Allocator::size_type
, which means that without further knowledge, we cannot simply assume that string::npos == -1
will even compile.
Now, as string
uses the default allocator (the template parameter has the default value in the typedef provided by the standard library after all), let us check 20.6.9:
typedef size_t size_type;
Now, we can essentially rewrite the question as: size_t(-1) == -1
. What happens now depends on the types of the subexpressions: The left hand side obviously has type size_t
, while the right hand side is an integer literal, which has type int
, when written like this (without further qualifiers).
The result is true
if size_t
is at least as large as int
(for standards fanatics: Has a larger or equal integer conversion rank as defined in 4.13). Otherwise, the left hand side will get promoted to int
, causing a comparision like 0xFFFF == -1
(for size_t
being uint16_t
and int
having 32 bit), which is false
.
Note that while 16 bit systems themselves are not very common anymore (except for some remnants in very small form factors), int
is not restricted to 32 bit by the standard. A compiler targetting x86_64 with 64
bit size_t
and 128 bit int
would be technically compliant.
All quotes are from the C++11 standard (ISO/IEC 14882:2011).