C++字符串联与 std::string 行为.请解释一下

C++ character concatenation with std::string behavior. Please explain this

本文关键字:解释 一下 行为 字符串 std string C++      更新时间:2023-10-16

这里有一些关于 c++ std::string 的情况,我无法理解。

1.

string ans = ""+'a';
cout << ans << endl; //Prints _string::copy

阿拉伯数字。

string ans="";
ans=ans+'a';
cout << ans << endl; //Prints a

3.

string ans="";
ans = ans + (5 + '0'); // Throws error

4.

string ans="";
ans += (5 + '0'); //works

5.

在代码中,我有一行 ans += to_string(q); q 是一个位数整数。程序抛出运行时错误。

将其更改为ans+= (q+'0');,错误被删除。

请帮助清除这个想法。

string ans = ""+'a';

" 是空字符串文本的地址。a' 被解释为整数,ASCII 代码 65。这会将 65 添加到文本字符串的地址,从而导致未定义的行为,可能是崩溃。

ans=ans+'a';

ans是一个std::string. std::string定义重载+运算符。实际上有几个。特别是其中之一,在参数为字符的情况下重载+,并将字符附加到字符串中。

ans = ans + (5 + '0'); // Throws error

5+'0'是提升为int类型的表达式。 std::string 不会明确地重载+运算符,并将int作为参数。这会导致编译错误。

ans += (5 + '0'); //works

std::string确实有一个明确的重载+=运算符,所以这编译得很好。

这个:

std::string ans = ""+'a';

不是你想的那样,你实际上执行的操作如下:

const char* p = "";
p = p + 97 /*97=='a'*/; // increase p pointer by `a` value, results in UB (pointer to random memory)
std::string ans = p; // p points to possibly unallocated memory (UB).

这没什么意义。

如果你用clang编译它,你会得到一长串的警告:

main.cpp:22:25: warning: adding 'char' to a string does not append to the string [-Wstring-plus-int]
    std::string ans = ""+'a';
                      ~~^~~~
main.cpp:22:25: note: use array indexing to silence this warning
    std::string ans = ""+'a';
                        ^
                      & [   ]
main.cpp:22:25: warning: adding 'char' to a string pointer does not append to the string [-Wstring-plus-char]
    std::string ans = ""+'a';
                      ~~^~~~
main.cpp:22:25: note: use array indexing to silence this warning
    std::string ans = ""+'a';
                        ^
                      & [   ]

字符串文字是一个字符数组。它不是std::string的实例。数组不能按值传递给函数或运算符,而是在使用操作数时衰减到指向第一个字符的指针。

字符是编码符号的数字。除 '' 外,所有字符都具有非零值。

在表达式 ""+'a' 中,字符串文字衰减为指针,然后'a'字符被迭代为非零整数。此值将添加到指针中。无论 a 的值如何(在常用的 ASCII 编码中恰好是 65(,结果都超出了数组的边界。指针算术越界具有未定义的行为,输出 1。是未定义行为的结果。


该计划 2. 具有明确定义和预期的行为。


ans = ans + (5 + '0'); // Throws error

没有接受std::stringint参数的operator+。右手参数int,因为 5 + '0' 中的char参数被提升为int,因此两个参数的类型相同。这也是表达式的返回类型。

这就是它变得毛茸茸的地方。有一个接受char operator+int可以转换为char。但是,还有其他可能的转换是不明确的。这是 clang 显示的错误:

error: invalid operands to binary expression ('string' (aka 'basic_string<char>') and 'int')
    ans = ans + (5 + '0'); // Throws error
          ~~~ ^ ~~~~~~~~~
./include/c++/6.1.0/bits/basic_string.h:4982:5: note: candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. 'int')
    operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
    ^
./include/c++/6.1.0/bits/basic_string.h:5036:5: note: candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. 'int')
    operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
^

。以及许多其他潜在的过载。


ans += (5 + '0'); //works

这是有效的operator+=(char);因为它是一个明确的重载。


在代码中,我有行 ans += to_string(q(; q 是一个位数整数。程序抛出运行时错误。

这里工作正常,没有抛出错误。