为什么在使用+ =将整数连接到字符串时,g ++不会发出警告/错误

Kod*_*Kid 4 c++ java g++ type-conversion implicit-conversion

我有这个代码:

#include <iostream>                     
using namespace std; 

int main()                  
{                                                                                    
       string name = "John ";                     
       int age = 32;         
       name += age;    
       cout << name << endl;
       return 0;                                          
}
Run Code Online (Sandbox Code Playgroud)

代码编译成功但在运行时背叛,因为它默默地忽略连接部分并打印:

John
Run Code Online (Sandbox Code Playgroud)

我知道我们需要使用stringstream来完成任务.但为什么上面的代码编译?因为以下代码:

#include <iostream>
using namespace std;                                                                 

int main()                       
{                                                                                    
       string name = "John ";                              
       int age = 55;                                    
       name = name + age;             
       cout << name << endl;      
       return 0;
} 
Run Code Online (Sandbox Code Playgroud)

适当抛出和错误:

错误:'name + age'中的'operator +'不匹配

我从Java中知道,与前一个构造a += b不同,a = a + b将结果类型化为a的类型. 参考.但我认为这在C++中并不重要,因为我们总能做到:

   int a = 1;                                                                       
   float f = 3.33;                                                                  
   a = a + f;
Run Code Online (Sandbox Code Playgroud)

与Java不同,不必担心可能会丢失精确警告.需要在C++中引用它.

所以现在如果我们假设name += age;扩展到name = string (name + age);那时代码也不应该仅仅因为name + age不合法而编译.

Sha*_*our 11

您需要使用该-Wconversion标志(我不清楚为什么它不包含在-Wall中)还可以查看请求或抑制警告选项以获取更多详细信息.当我添加该标志时,我在使用时看到以下警告gcc:

 warning: conversion to 'char' from 'int' may alter its value [-Wconversion]
    name += age;  
         ^
Run Code Online (Sandbox Code Playgroud)

我们可以看到,运算符+ =确实支持char,因此转换后的值确实被添加到结尾name,它根本不会忽略该操作.在C++中, operator + for std :: string是一个与operator + =不同的运算.

在这个特定情况下:

name += age;
Run Code Online (Sandbox Code Playgroud)

会翻译成这样的东西:

name.operator+=(static_cast<char>(age)) ;
Run Code Online (Sandbox Code Playgroud)

如果我们有一个使用operator +的表达式而没有像这样的错误:

name = name + static_cast<char>( age );
Run Code Online (Sandbox Code Playgroud)

会转化为:

operator+( name, static_cast<char>( age ) ) ;
Run Code Online (Sandbox Code Playgroud)

在这个答案中很好地解释了为什么在你的例子中为operator +失败的原因,基本上模板函数不会执行转换,因此需要与const/volatile限定符的可能异常完全匹配.

Wconversion更新

gcc有一个带有常见问题解答Wconversion Wiki,它有点过时但它确实回答了为什么这个检查不包括在旗帜中:-Wall

隐式转换在C中非常常见.这与前端没有数据流(参见下一个问题)的结果相关,导致难以避免完美工作和有效代码的警告.Wconversion设计用于特定用途(安全审计,将32位代码移植到64位等),程序员愿意接受并解决无效警告.因此,如果未明确请求,则不应启用它.