[英]C++ character concatenation with std::string behavior. Please explain this
Here are some cases about c++ std::string which I couldn't understand. 以下是关于c ++ std :: string的一些我无法理解的案例。
1. 1。
string ans = ""+'a';
cout << ans << endl; //Prints _string::copy
2. 2。
string ans="";
ans=ans+'a';
cout << ans << endl; //Prints a
3. 3。
string ans="";
ans = ans + (5 + '0'); // Throws error
4. 4。
string ans="";
ans += (5 + '0'); //works
5. 5。
In a code, I had the line ans += to_string(q);
在代码中,我有一行
ans += to_string(q);
q was a single digit integer. q是单个数字整数。 The program threw runtime error.
该程序引发了运行时错误。
Changed it to ans+= (q+'0');
将其更改为
ans+= (q+'0');
and the error got removed. 并删除了错误。
Please help with clearing the idea. 请帮助清除这个想法。
string ans = ""+'a';
"" is an address of an empty string literal. “”是空字符串文字的地址。 'a' gets interpreted as an integer, ASCII code 65. This adds 65 to an address of a literal string, which results in undefined behavior, possibly a crash.
'a'被解释为整数,ASCII码65.这会将65添加到文字字符串的地址,这会导致未定义的行为,可能是崩溃。
ans=ans+'a';
ans
is a std::string
. ans
是一个std::string
。 std::string
defines an overloaded +
operator. std::string
定义了一个重载的+
运算符。 Several, actually. 实际上有几个。 One of them, in particular, overloads
+
where the parameter is a character, and it appends the character to the string. 其中之一,特别是重载
+
参数是一个字符,并将字符附加到字符串。
ans = ans + (5 + '0'); // Throws error
5+'0'
is an expression that's promoted to an int
type. 5+'0'
是一个被提升为int
类型的表达式。 std::string
does not unambiguously overload the +
operator with an int
as the parameter. std::string
没有明确地使用int
作为参数来重载+
运算符。 This result in a compilation error. 这导致编译错误。
ans += (5 + '0'); //works
std::string
does have an unambigous overloaded +=
operator, so this compiles fine. std::string
确实有一个不明显的重载+=
运算符,所以编译得很好。
This: 这个:
std::string ans = ""+'a';
is not what you think, you actually perform the same operation as below: 不是你的想法,你实际执行的操作如下:
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).
which makes little sense. 这没什么意义。
if you compile it with clang you will get long list of warnigns: 如果你用clang编译它,你会获得很长的warnigns列表:
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';
^
& [ ]
String literal is an array of characters. 字符串文字是一个字符数组。 It it not an instance of
std::string
. 它不是
std::string
的实例。 Arrays cannot be passed to functions or operators by value, but instead they decay to a pointer to first character, when used an operand. 数组不能通过值传递给函数或运算符,而是在使用操作数时它们衰减为指向第一个字符的指针。
Characters are numbers that encode symbols. 字符是编码符号的数字。 All characters have a non-zero value, except for
'\\0'
. 除
'\\0'
外,所有字符都具有非零值。
In the expression ""+'a'
, the string literal decays to pointer, then 'a'
character is iterpreted as a non-zero integer. 在表达式
""+'a'
,字符串文字衰减到指针,然后'a'
字符被解释为非零整数。 This value is added to the pointer. 该值将添加到指针中。 Regardless of the value of
a
(It happens to be 65 in the commonly used ASCII encoding), the result is beyond the bounds of the array. 无论
a
的值如何(在常用的ASCII编码中恰好是65),结果都超出了数组的范围。 Pointer arithmetic out of bounds has undefined behaviour, and the output 1. is the result of the undefined behaviour. 超出范围的指针算法具有未定义的行为,输出1.是未定义行为的结果。
The program 2. has well defined and expected behaviour. 程序2.具有明确定义和预期的行为。
ans = ans + (5 + '0'); // Throws error
There is no operator+
that accepts arguments std::string
and int
. 没有
operator+
接受参数std::string
和int
。 The right hand argument is int
because the char
argument in 5 + '0'
is promoted to int
so that both arguments are of same type. 右手参数是
int
因为5 + '0'
的char
参数被提升为int
因此两个参数的类型相同。 This is also the return type of the expression. 这也是表达式的返回类型。
This is where it gets hairy. 这是毛茸茸的地方。 There is an
operator+
that accepts char
and int
is convertible to char
. 有一个
operator+
接受char
, int
可以转换为char
。 However, there are also other possible conversions that are ambiguous. 但是,还有其他可能的转换模糊不清。 Here is the error shown by clang:
这是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,
^
... And many other potential overloads. ......以及许多其他潜在的超载。
ans += (5 + '0'); //works
This works because operator+=(char);
这是因为
operator+=(char);
is an unambiguous overload. 是一个明确的超载。
In a code, I had the line ans += to_string(q);
在代码中,我有一行ans + = to_string(q); q was a single digit integer.
q是单个数字整数。 The program threw runtime error.
该程序引发了运行时错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.