标题相对自我解释。我认识到与其他答案的相似性,但所有这些答案都有不同的运算符排列(因此不同的演员规则)。所以我需要一个澄清这个特例的答案。
如果有人可以指出解释这一点的标准部分,我会很乐意投票并接受答案。
答案 0 :(得分:8)
否,并非总是如此。然而,它比初看起来要复杂一点:
首先,让我们看看std::string
是什么(21.3 / 1):
标题
<string>
定义用于操作变长序列的basic_string
类模板 类似于char的对象和四个typedef,string
,u16string
,u32string
和wstring
,它们命名为特化 分别为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 == -1
(size_t
为uint16_t
和int
之间的比较有32位),这是false
。
请注意,虽然16位系统本身不再常见(除了一些非常小的外形中的残余),int
不受标准限制为32位。使用64
位size_t
和128位int
定位x86_64的编译器在技术上是合规的。
所有引用均来自C ++ 11标准(ISO / IEC 14882:2011)。
答案 1 :(得分:5)
你提出的问题存在漏洞。
如果int
(严格地)具有比string::size_type
更大的整数转化率,并且int
可以存储string::size_type
的全部值,则string::npos == -1
将int
是假的,因为两个论点都会被提升为string::size_type
,而不是被提升为"\\W+"
。
发生这种情况的环境会非常不寻常。
这来自通常的算术转换:
...
否则,如果具有无符号整数类型的操作数的等级大于或等于 另一个操作数的类型的等级,带有符号整数类型的操作数应转换为 具有无符号整数类型的操作数的类型
否则,如果带有符号整数类型的操作数的类型可以表示的所有值 具有无符号整数类型的操作数的类型,具有无符号整数类型的操作数应为 转换为带有符号整数类型的操作数的类型。
否则,两个操作数都应转换为对应的无符号整数类型 带有符号整数类型的操作数的类型。
答案 2 :(得分:2)