繁体   English   中英

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

[英]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::stringint 右手参数是int因为5 + '0'char参数被提升为int因此两个参数的类型相同。 这也是表达式的返回类型。

这是毛茸茸的地方。 有一个operator+接受charint可以转换为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.

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