简体   繁体   English

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

[英]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::stringint 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+接受charint可以转换为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. 该程序引发了运行时错误。

Works fine here, no errors thrown. 在这里工作正常,没有错误抛出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM