[英]Why does g++ not warn/err while concatenating an integer to a string using +=
我有這個代碼:
#include <iostream>
using namespace std;
int main()
{
string name = "John ";
int age = 32;
name += age;
cout << name << endl;
return 0;
}
代碼編譯成功但在運行時背叛,因為它默默地忽略連接部分並打印:
John
我知道我們需要使用stringstream來完成任務。 但為什么上面的代碼編譯? 因為以下代碼:
#include <iostream>
using namespace std;
int main()
{
string name = "John ";
int age = 55;
name = name + age;
cout << name << endl;
return 0;
}
適當拋出和錯誤:
錯誤:'name + age'中的'operator +'不匹配
我從Java中知道a += b
與a = a + b
不同,因為前一個構造將結果類型化為a = a + b
的類型。 參考 。 但我認為這在C ++中並不重要,因為我們總能做到:
int a = 1;
float f = 3.33;
a = a + f;
與Java不同,不必擔心可能會丟失精確警告。 需要在C ++中引用它。
所以現在我們假設name += age;
擴展為name = string (name + age);
那么代碼也不應該簡單編譯因為name + age不合法。
您需要使用-Wconversion
標志( 我不清楚為什么它不包含在-Wall中 )還可以查看請求或抑制警告的選項以獲取更多詳細信息。 當我添加該標志時,我在使用gcc
時會看到以下警告:
warning: conversion to 'char' from 'int' may alter its value [-Wconversion]
name += age;
^
我們可以看到operator + =確實支持char ,因此轉換后的值確實被添加到name
的末尾,它根本不會忽略該操作。 在C ++中, operator + for std :: string是一個與operator + =不同的運算符 。
在這個特定情況下:
name += age;
會翻譯成這樣的東西:
name.operator+=(static_cast<char>(age)) ;
如果我們有一個使用operator +的表達式而沒有像這樣的錯誤:
name = name + static_cast<char>( age );
會轉化為:
operator+( name, static_cast<char>( age ) ) ;
在這個答案中很好地解釋了為什么在你的例子中運算符+失敗的原因,基本上模板函數不會執行轉換,所以需要與const / volatile限定符的可能例外完全匹配。
Wconversion更新
gcc
有一個帶有常見問題解答的Wconversion Wiki ,它有點過時但它確實回答了為什么這個檢查不包含在-Wall
標志中:
隱式轉換在C中非常常見。這與前端沒有數據流(參見下一個問題)的結果相關,導致難以避免完美工作和有效代碼的警告。 Wconversion設計用於特定用途(安全審計,將32位代碼移植到64位等),程序員願意接受並解決無效警告。 因此,如果未明確請求,則不應啟用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.