我发现std::string
C++0x 中的字符串文字和字符串文字之间存在令人不安的不一致:
#include <iostream>
#include <string>
int main()
{
int i = 0;
for (auto e : "hello")
++i;
std::cout << "Number of elements: " << i << '\n';
i = 0;
for (auto e : std::string("hello"))
++i;
std::cout << "Number of elements: " << i << '\n';
return 0;
}
输出是:
Number of elements: 6
Number of elements: 5
我理解为什么会发生这种情况的机制:字符串文字实际上是一个包含空字符的字符数组,并且当基于范围的 for 循环调用std::end()
字符数组时,它会获得一个超出数组末尾的指针;由于空字符是数组的一部分,因此它会获得一个越过空字符的指针。
但是,我认为这是非常不可取的:std::string
当涉及到像它们的长度一样基本的属性时,字符串文字肯定应该表现得相同吗?
有没有办法解决这种不一致?例如,对于字符数组是否可以std::begin()
和std::end()
被重载,以使它们分隔的范围不包括终止空字符?如果是这样,为什么没有这样做?
编辑:为了证明我对那些说我只是遭受使用作为“遗留功能”的 C 样式字符串的后果的人的愤慨,请考虑如下代码:
template <typename Range>
void f(Range&& r)
{
for (auto e : r)
{
...
}
}
你会期望f("hello")
并f(std::string("hello"))
做一些不同的事情吗?