std :: string和字符串字符之间不一致 [英] Inconsistency between std::string and string literals

查看:301
本文介绍了std :: string和字符串字符之间不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了 std :: string 和C ++ 0x中的字符串文字之间的令人不安的不一致:

I have discovered a disturbing inconsistency between std::string and string literals in 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

我理解为什么会发生这种情况的机制:字符串字面值是一个包含空字符的字符数组,当基于范围的循环调用 std :: end )在字符数组,它获取一个指针超过数组的末尾;因为空字符是数组的一部分,所以它获得了一个指向空字符的指针。

I understand the mechanics of why this is happening: the string literal is really an array of characters that includes the null character, and when the range-based for loop calls std::end() on the character array, it gets a pointer past the end of the array; since the null character is part of the array, it thus gets a pointer past the null character.

但是,我认为这是非常不可取的:肯定 std :: string 和字符串字面值在它们的长度基本属性时应该是一样的吗?

However, I think this is very undesirable: surely std::string and string literals should behave the same when it comes to properties as basic as their length?

解决这个不一致?例如,可以为字符数组重载 std :: begin() std :: end()它们分隔的范围不包括终止空字符?如果是,为什么不这样做?

Is there a way to resolve this inconsistency? For example, can std::begin() and std::end() be overloaded for character arrays so that the range they delimit does not include the terminating null character? If so, why was this not done?

EDIT :为了证明我的愤慨,遭受使用作为遗留特征的C风格字符串的后果,考虑如下代码:

EDIT: To justify my indignation a bit more to those who have said that I'm just suffering the consequences of using C-style strings which are a "legacy feature", consider code like the following:

template <typename Range>
void f(Range&& r)
{
    for (auto e : r)
    {
        ...
    }
}

您会期望 f(hello) f(std :: string(hello))做不同的事情吗?

Would you expect f("hello") and f(std::string("hello")) to do something different?

推荐答案

不一致可以使用C ++ 0x的工具箱中的另一个工具来解决:用户定义的文字。使用适当定义的用户定义文字:

The inconsistency can be resolved using another tool in C++0x's toolbox: user-defined literals. Using an appropriately-defined user-defined literal:

std::string operator""s(const char* p, size_t n)
{
    return string(p, n);
}

我们可以这样写:

int i = 0;     
for (auto e : "hello"s)         
    ++i;     
std::cout << "Number of elements: " << i << '\n';

现在输出预期的数字:

Number of elements: 5

字符串文字,可以说没有更多的理由使用C风格的字符串文字,永远。

With these new std::string literals, there is arguably no more reason to use C-style string literals, ever.

这篇关于std :: string和字符串字符之间不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆