std :: string :: npos == -1总是如此吗?

时间:2015-06-06 17:46:35

标签: c++ casting language-lawyer

标题相对自我解释。我认识到与其他答案的相似性,但所有这些答案都有不同的运算符排列(因此不同的演员规则)。所以我需要一个澄清这个特例的答案。

如果有人可以指出解释这一点的标准部分,我会很乐意投票并接受答案。

3 个答案:

答案 0 :(得分:8)

,并非总是如此。然而,它比初看起来要复杂一点:

首先,让我们看看std::string是什么(21.3 / 1):

  

标题<string>定义用于操作变长序列的basic_string类模板   类似于char的对象和四个typedef,stringu16stringu32stringwstring,它们命名为特化   分别为basic_string<char>basic_string<char16_t>basic_string<char32_t>basic_string<wchar_t>

从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使用默认分配器(模板参数在标准库提供的typedef中具有默认值),让我们检查20.6.9:

typedef size_t size_type;

现在,我们基本上可以将问题重写为:size_t(-1) == -1。现在发生的事情取决于子表达式的类型:左侧显然具有类型size_t,而右侧是整数文字,其类型为int,当这样写时(没有进一步的)限定符)。

如果true至少与size_t一样大,则结果为int(对于标准狂热分子:具有4.13中定义的更大的整数转换排名)。否则,左侧将升级为int,从而导致0xFFFF == -1size_tuint16_tint之间的比较有32位),这是false

请注意,虽然16位系统本身不再常见(除了一些非常小的外形中的残余),int不受标准限制为32位。使用64size_t和128位int定位x86_64的编译器在技术上是合规的。

所有引用均来自C ++ 11标准(ISO / IEC 14882:2011)。

答案 1 :(得分:5)

你提出的问题存在漏洞。

如果int(严格地)具有比string::size_type更大的整数转化率,并且int可以存储string::size_type的全部值,则string::npos == -1int是假的,因为两个论点都会被提升为string::size_type,而不是被提升为"\\W+"

发生这种情况的环境会非常不寻常。

这来自通常的算术转换

  

...

     

否则,如果具有无符号整数类型的操作数的等级大于或等于   另一个操作数的类型的等级,带有符号整数类型的操作数应转换为   具有无符号整数类型的操作数的类型

     

否则,如果带有符号整数类型的操作数的类型可以表示的所有值   具有无符号整数类型的操作数的类型,具有无符号整数类型的操作数应为   转换为带有符号整数类型的操作数的类型。

     

否则,两个操作数都应转换为对应的无符号整数类型   带有符号整数类型的操作数的类型。

答案 2 :(得分:2)

是的,它被定义为-1

N4296§21.4/ 5提供std::basic_string的类模板,其中包含行

static const size_type npos = -1;