[英]C++ character concatenation with std::string behavior. Please explain this
以下是关于c ++ std :: string的一些我无法理解的案例。
1。
string ans = ""+'a';
cout << ans << endl; //Prints _string::copy
2。
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编译它,你会获得很长的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';
^
& [ ]
字符串文字是一个字符数组。 它不是std::string
的实例。 数组不能通过值传递给函数或运算符,而是在使用操作数时它们衰减为指向第一个字符的指针。
字符是编码符号的数字。 除'\\0'
外,所有字符都具有非零值。
在表达式""+'a'
,字符串文字衰减到指针,然后'a'
字符被解释为非零整数。 该值将添加到指针中。 无论a
的值如何(在常用的ASCII编码中恰好是65),结果都超出了数组的范围。 超出范围的指针算法具有未定义的行为,输出1.是未定义行为的结果。
程序2.具有明确定义和预期的行为。
ans = ans + (5 + '0'); // Throws error
没有operator+
接受参数std::string
和int
。 右手参数是int
因为5 + '0'
的char
参数被提升为int
因此两个参数的类型相同。 这也是表达式的返回类型。
这是毛茸茸的地方。 有一个operator+
接受char
, 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是单个数字整数。 该程序引发了运行时错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.