2015-06-06 62 views
7

標題相對自我解釋。我認識到與其他答案的相似之處,但所有這些人都有不同的操作員安排(因此也有不同的施法規則)。所以我需要一個解釋這個特殊情況的答案。是std :: string :: npos == -1總是正確的?

如果有人能指出解釋這個標準的部分,我會很樂意投票並接受答案。

回答

7

,它並不總是如此。然而,這是一個比較複雜一點比它乍看起來:

在開始的時候,讓我們看到了什麼std::string是(21.3/1):

<string>定義basic_string類模板操縱變長序列焦炭狀物體的 和四個類型定義,stringu16stringu32string,和wstring,該名稱的特 basic_string<char>basic_string<char16_t>basic_string<char32_t>,和basic_string<wchar_t>,respectiv伊利。

開始了以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] 
}; 

注意的是,雖然npos-1初始化,它的類型取決於Allocator::size_type,這意味着,如果沒有進一步的知識,我們不能簡單地假設那string::npos == -1甚至會編譯。

現在,string使用默認分配器(模板參數在標準庫後所提供的所有類型定義默認值),讓我們檢查20.6.9:

typedef size_t size_type; 

現在,我們可以基本上將這個問題重寫爲:size_t(-1) == -1。現在發生什麼取決於子表達式的類型:左手邊顯然有size_t類型,而右手邊是整數字面值,類型爲int,這樣寫(沒有進一步限定符)。

結果是true如果size_t是至少一樣大int(對標準的狂熱分子:具有如4.13所定義的較大的整數轉換秩)。否則,左手邊將得到提升到int,導致像0xFFFF == -1一個對比(對於size_tuint16_tint具有32位),這是false

請注意,雖然16位系統本身不再是非常普遍的(除了一些殘餘物的外形非常小),int並不侷限於標準的32位。目標x86_64與64size_t和128位int的編譯器將在技術上符合。

所有引用來自C++ 11標準(ISO/IEC 14882:2011)。

+0

作爲後續問題,首先將左側的類型轉換爲帶符號的類型會導致表達式得到保證?例如:'(signed size_t)std :: string :: npos == -1' – randomusername

+0

@randomusername該轉換導致未定義的行爲,因爲'npos'的值很大。只需執行以下操作:'std :: string :: npos == std :: string :: size_type(-1)',你很好。 –

2

是的,它被定義爲-1

N4296§21.4/10提供了類模板std::basic_string其中包括線

static const size_type npos = -1; 
5

沒有爲你從字面上問問題的漏洞。

如果int有(嚴格)更大的整數轉換等級上低於string::size_typeint可以存儲全系列string::size_type值,然後string::npos == -1將是錯誤的,因爲這兩個參數會得到晉升爲int,而不是被晉升爲string::size_type

發生這種情況的環境相當不尋常。

這個來自通常的算術轉換

...

否則,如果具有無符號整數類型操作數的秩大於或等於類型的 排名另一個操作數的帶符號整數類型的操作數應轉換爲 帶無符號整數類型的操作數的類型

否則,如果操作數的類型帶有符號整數類型的rand可以表示所有具有無符號整數類型的操作數的類型的值 ,具有無符號整數類型的操作數應將 轉換爲具有有符號整數類型的操作數的類型。

否則,兩個操作數都應轉換爲無符號整數類型,對應於有符號整數類型的操作數的 類型。

+0

那麼你是否暗示'string :: size_type'不會在符號擴展中轉換爲'int'? – randomusername

+0

@randomusername:'string :: size_type'是無符號的,所以沒有符號位可以擴展;該轉換保留了該值,因此它將轉換爲非負「int」。請注意,'npos'是一個正值:實際上,它是可存儲在'string :: size_type'中的最大值。 – Hurkyl

相關問題