[英]Concatenation of std::string and int leads to a shift. Why?
今天,當我嘗試將std::string
與int
連接時,我感到很驚訝。 考慮以下 MWE:
#include <iostream>
#include <string>
void print(const std::string& text)
{
std::cout << "The string is: " << text << ".\n";
}
int main()
{
print("iteration_" + 1);
return 0;
}
而不是打印
The string is: iteration_1.
我希望,它打印
The string is: teration_.
后台到底發生了什么? 字符串是否由於某種原因被轉換為char[]
或類似的東西? operator+ 的文檔沒有列出任何帶有std::string
和int
的內容。
將std::string
與數字連接的正確方法是什么? 我真的必須將它們都放入std::stringstream
或使用std::to_string()
將數字顯式轉換為std::string
嗎?
這條線是問題所在:
print("iteration_" + 1);
字符串文字正在衰減為char*
。 您正在向此char*
添加1
,將其移動到下一個字符。
如果您想將字符串"1"
添加到文字的末尾,一種相當簡單的方法是將字符串文字傳遞給std::string
構造函數並手動將1
轉換為字符串。 例如:
print(std::string("iteration_") + std::to_string(1));
字符串是否由於某種原因被轉換為 char[]
事實上,情況恰恰相反。 "iteration_"
是一個char[11]
,當您添加1
時它會衰減為const char*
。 將指針加一使其指向字符串中的下一個字符。 然后使用它來構造一個臨時的std::string
,它包含除第一個字符之外的所有字符。
您鏈接的文檔適用於std::string
的operator+
,但要使用它,您首先需要std::string
。
"iteration_"
不是std::string
,而是const char[]
。 衰減到const char*
,而"iteration_" + 1
只是執行指針算術並將指針移動到下一個char
(即't'
),然后你就得到了 c 風格的字符串"teration_"
。
您可以使用std::to_string
將int
轉換為std::string
,然后將它們連接起來。 例如
print("iteration_" + std::to_string(1));
對於這種情況,調用std::operator+(std::basic_string)並將第一個參數"iteration_"
隱式轉換為std::string
然后傳遞給operator+
,然后將連接的std::string
傳遞給print
。
如果您嘗試使用以下內容:
std::string str = "iteration" + 1;
編譯器會拋出警告:
警告:將“int”添加到字符串不會 append 到字符串 [-Wstring-plus-int]
這是因為您將指向“迭代”字符串的指針增加 1,這意味着現在“迭代”字符串被分配給str
變量。
連接的正確方法是:
std::string str = "iteration" + std::to_string(1);
表達式"iteration_" + 1
是添加到int
1 的const char[11]
文字。
在該表達式中, "iteration_"
衰減為指向數組第一個元素的const char*
指針。 + 1
然后發生在該指針的指針算術中。 整個表達式的計算結果為const char*
類型(指向第一個t
),它是std::string
構造函數的有效 NUL 終止輸入! (匿名臨時std::string
綁定到const std::string&
function 參數。)
這是完全有效的 C++,偶爾可以很好地使用。
如果您想將+
視為串聯,則
print("iteration_" + std::to_string(1));
是一種方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.