C++ 字符串的std::end是否应该指向空终止符?

C++ 字符串的std::end是否应该指向空终止符?,c++,c++11,iterator,C++,C++11,Iterator,我注意到,当涉及字符串或字符数组时,std::end将始终引用空终止符。我认为std::end应该是指最后一个有效元素后面的数组末尾。“\0”是否被视为无效元素?它是阵列的一部分。以下是所有返回true的测试: #include <iostream> int main() { std::string s("hello!"); auto s_end = *(s.data() + s.size() + 1); std::cout << std::bo

我注意到,当涉及字符串或字符数组时,
std::end
将始终引用空终止符。我认为
std::end
应该是指最后一个有效元素后面的数组末尾。
“\0”
是否被视为无效元素?它是阵列的一部分。以下是所有返回true的测试:

#include <iostream>

int main()
{
    std::string s("hello!");
    auto s_end = *(s.data() + s.size() + 1);
    std::cout << std::boolalpha  << (*std::end(s) == s_end) << "\n"
              << (s_end == '\0') << "\n";
    char buf[6 + 1];
    std::copy(s.begin(), s.end(), &buf[0]);
    auto buf_end = *(buf + s.size() + 1);
    std::cout << (*std::end(buf) == buf_end) << "\n"
              << (buf_end == '\0') << "\n";

    char test[3] = {'h', '\0', 'e'};
    std::cout << (*std::end(test) == '\0');
    return 0;
}
#包括
int main()
{
std::字符串s(“你好!”);
自动s_端=*(s.data()+s.size()+1);

std::cout对于字符数组,
std::end
确实指向数组中的最后一个字符。对于

char test[3] = {'h', '\0', 'e'};
指针
std::end(test)
test+3
相同。取消引用它与评估
test[3]相同
。这是未定义的行为。在您的特定情况下,它恰好生成了
'\0'
。但一般来说,它可能会生成不同的值,或者崩溃,或者完全是其他原因。
std::end(test)
是否指向数组
test
中索引1处的
'\0'
字符

请注意,
std::end
对所有数组的行为是一致的。也就是说,如果我们有一个数组
ta[N]
,那么
std::end(a)
返回
a+N
,无论
T
char
还是
a
的内容是什么。它不给字符串的结尾,而是给数组的结尾。同样,返回值总是
a+N
。没有例外

对于
std::string
,有一个终止的空字符,但它不被视为字符串的一部分。(与其他字符不同,由于行为未定义,不允许修改它。)如果

std::string s("hello");
然后
s[5]
将具有空字符的值,但正如我所说的,它不被视为字符串的一部分:
s
被视为有五个字符,而不是六个。最好将
std::string
视为根本没有以空结尾。最后一个字符是
s[4]
具有值
'o'
,并且
std::end(s)
是刚刚经过
std::begin(s)+4
的迭代器,即
std::begin(s)+5


这比看起来要微妙一些,因为标准在技术上不能保证
std::end(s)
完全是可取消引用的,因此您不一定要说它指向终止null。实际上,它确实指向终止null,但取消引用它仍然是未定义的行为。

end
迭代器是不可取消引用的。通过取消引用它,您的程序显示未定义的行为。空终止符不是被认为存储在
std::string
中的部分内容。例如,它不包含在
size()
中,也不由
back()
返回。根据C++11标准及以后的标准,它不能是std::string的未定义行为(是的,它很混乱)。从技术上来说,它确实保证了std::string的可区分性。std::string现在具有非常明确的行为,即要求连续并在末尾包含空字符。
std::string.begin()
std::string.data()
std::string.c_str()
,以及
&std::string[0]
,根据规则,它们都指向同一个位置。因此,end和string的一般规则在语言定义中存在冲突。