【发布时间】:2011-10-07 07:56:49
【问题描述】:
我发现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")) 做一些不同的事情?
【问题讨论】:
-
这是一个真实的问题吗?它更像是关于标准应该是什么而不是它是什么的个人意见。
-
基于一些答案和 cmets,我现在想知道负责确定未来 C++ 版本功能的人员是否考虑为
std::string字符串添加新的字符串文字语法。我的意思是,Objective-C 和 C# 都使用@""来表示非 C 风格的字符串文字,即使在 C 和 C++ 中,您也可以使用L""语法来表示宽字符串文字。 (而且似乎L''可以用来表示文字wchars?) -
@JAB: 字符串字面量到底有什么问题,需要另一种内置类型?
-
@Gene:当整数类型完美地满足目的时,为什么 C 实现了布尔类型?
-
@JAB:在 C++0x 中,您将能够通过用户定义的文字为
std::string创建一个新的字符串文字语法。
标签: c++ string foreach c++11 string-literals