为什么 t+=i+'a' 给出正确的输出,而 t=t+i+'a' 给出错误?

Anu*_*nuj 9 c++ string

我一直在研究一些涉及将 ASCII 值转换为字符串的问题。

如果我使用此代码,我得到的输出为g,这是预期的。

using namespace std;
int main()
{
    int i=6; vector<string> ans;
    string t= "";

    t+=i+'a';

    ans.push_back(t);
    cout<<ans[0];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我像这样更改代码:

using namespace std;
int main()
{
    int i=6; vector<string> ans;
    string t= "";

    t=t+i+'a';        // <----

    ans.push_back(t);
    cout<<ans[0];

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译它时,显示以下错误:

error: no match for 'operator+' (operand types are 'std::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')

7 | t=t+i+'a';
  |   ~^~
  |   | |
  |   | int
  |   std::string {aka std::__cxx11::basic_string<char>}
Run Code Online (Sandbox Code Playgroud)

两个代码之间的唯一区别是,在第一个代码中,我使用的是t+=i+'a';,而在第二个代码中,我t=t+i+'a';使用的是 。

有人可以告诉我第二个片段有什么问题吗?

Dan*_*ica 11

一、t += i + 'a';案例

在这里,有两件事很重要。第一的

std::string& std::string::operator+=(char ch);
Run Code Online (Sandbox Code Playgroud)

被调用,它是类(即类模板实例)的非模板成员函数;请参阅https://en.cppreference.com/w/cpp/string/basic_string/operator%2B%3Dstd::stringstd::basic_string<char>

其次,类型i + 'a'int

一切正常,因为i + 'a'type 的参数int可以用作 type 的函数参数的参数char

2、t = t + i + 'a';案例

与情况 1 不同,operator+这里使用的是。首先对于t + i部分,其中i是类型int(有关原因的详细信息,请参阅@AnoopRana 的答案)。但是opeartor+是一个免费(非会员)的功能模板;请参阅https://en.cppreference.com/w/cpp/string/basic_string/operator%2B

编译器尝试实例化这个定义:

template<class CharT, class Traits, class Alloc>
std::basic_string<CharT,Traits,Alloc>
operator+( const std::basic_string<CharT,Traits,Alloc>& lhs, CharT rhs );
Run Code Online (Sandbox Code Playgroud)

但它不能,因为:

  1. 根据类型 的第一个参数std::stringCharT将推导出为char
  2. 根据类型 的第二个参数intCharT将被推导为int

因此,就会出现演绎冲突。并且,没有其他可以实例化的模板。


同一问题的简单演示代码:

template <typename Char>
struct String
{
    String& operator+=(Char);
};

template <typename Char>
String<Char> operator+(const String<Char>&, Char);

int main()
{
    String<char> s;
    s += 2 + 'a';
    s = s + 2 + 'a';
}
Run Code Online (Sandbox Code Playgroud)

实时链接: https: //godbolt.org/z/MonK1e3bq

  • @MarekR嗯,运算符优先级在这里并不重要,我们可以在*没有*`+ 'a'`的情况下重现问题:https://godbolt.org/z/c7anTed1d。但请注意,他们说:*“这里使用了`operator+`,**首先用于`t + i`部分**,其中`i`是`int`类型。”*。 (3认同)

use*_*570 -1

情况 2 中的问题是,由于运算符优先级,该语句实际上被分组为t = t + i + 'a'或等效于)。t = (t + i) + 'a'

//---v---v--------->t is std::string while i is an int
t = (t + i) + 'a'; //equivalent to this due to operator precedence
Run Code Online (Sandbox Code Playgroud)

现在 as tis astd::stringiis anint并且由于没有重载operator+需要 anstd::string和 a int,我们得到了提到的错误。


请注意是一个算术运算符,因此在第一种情况下,写入 时+字符文字'a'被提升为。由于有可以使用的重载,第一种情况使用重载。inti + 'a'std::string string& string::operator+= (char)operator+=