NO, es ist nicht immer wahr. Es ist jedoch ein wenig komplizierter, als es auf den ersten Blick scheint:
Am Anfang, lassen Sie uns sehen, was std::string
ist (21,3/1):
Der Header <string>
definiert die basic_string
Klassenvorlage für die Manipulation variierende Längensequenzen von kohleartigen Objekten und vier typedefs, string
, u16string
, u32string
und wstring
, dass die Namen Spezialisierungen basic_string<char>
, basic_string<char16_t>
, basic_string<char32_t>
und basic_string<wchar_t>
, JEWEILIGEN ely.
beginnen mit 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]
};
Beachten Sie, dass während npos
mit -1
initialisiert wird, seine Art auf Allocator::size_type
abhängt, was bedeutet, dass ohne weiteres Wissen, können wir nicht einfach davon ausgehen, dass string::npos == -1
wird sogar kompilieren.
Jetzt, da string
das Standard-Allocator verwendet (die Template-Parameter den Standardwert in der typedef von der Standardbibliothek zur Verfügung gestellt, nachdem alle haben), lassen Sie uns 20.6.9 überprüfen:
typedef size_t size_type;
Nun können wir die Frage im Wesentlichen wie folgt umschreiben: size_t(-1) == -1
. Was nun passiert, hängt von den Typen der Teilausdrücke ab: Die linke Seite hat offensichtlich den Typ size_t
, während die rechte Seite ein ganzzahliges Literal ist, das den Typ int
hat, wenn es so geschrieben wird (ohne weitere Qualifier).
Das Ergebnis ist true
size_t
wenn die mindestens so groß ist wie int
(Normen Fanatiker: hat einen größeren Ganzzahl-Umwandlungs Rang wie in 4.13 definiert). Andernfalls wird die linke Seite zu int
befördert zu werden, wie ein Vergleich 0xFFFF == -1
verursacht (für size_t
uint16_t
und int
wobei 32 Bit aufweist), die false
ist.
Beachten Sie, dass 16-Bit-Systeme selbst nicht mehr sehr häufig sind (abgesehen von einigen Überresten in sehr kleinen Formfaktoren), int
ist nicht auf 32-Bit vom Standard beschränkt. Ein Compiler, der x86_64 mit 64
Bit size_t
und 128 Bit int
anvisiert, wäre technisch kompatibel.
Alle Zitate stammen aus dem C++ 11 Standard (ISO/IEC 14882: 2011).
Als eine Folgefrage würde zuerst die Umwandlung des Typs der linken in einen vorzeichenbehafteten Typ bewirken, dass der Ausdruck garantiert wird? Zum Beispiel: '(signed size_t) std :: string :: npos == -1' – randomusername
@randomusername Diese Konvertierung führt zu undefiniertem Verhalten, da der Wert von 'npos' zu groß ist. Mach einfach folgendes: 'std :: string :: npos == std :: string :: size_type (-1)' und alles geht gut. –