int
をstd::string
に追加する2つの異なる方法を試しましたが、驚いたことに、異なる結果が得られました。
#include <string>
int main()
{
std::string s;
s += 2; // compiles correctly
s = s + 2; // compiler error
return 0;
}
+=
演算子を使用すると正常にコンパイルおよび動作しますが、+
演算子を使用すると失敗します。
質問は std :: stringとintを連結する方法 のようなものではないと思います
その質問では、+=
演算子を使用する答えはありません。そして、+=
と+
のstd::string
演算子の違いは、疑問を解決するための鍵です。
率直に言って、この質問は、c ++の習得が非常に難しい理由を説明する良い例です。
TL; DRoperator+=
はclass string
のクラスメンバー関数であり、operator+
はテンプレート関数です。
標準クラスtemplate<typename CharT> basic_string<CharT>
にはオーバーロード関数basic_string& operator+=(CharT)
があり、文字列はbasic_string<char>
にすぎません。
式s += 2
では、下位の型に適合する値をその型に自動的にキャストできるため、2はnotとしてint
として扱われますが、代わりにchar
として扱われます。 exactlys += '\x02'
と同じ効果があります。 ASCIIコード2(STX)の文字が追加され、not文字 '2'(ASCIIで) _値50、または0x32)。
ただし、stringにはstring operator+(int)
のようなオーバーロードされたメンバー関数がありません。s + 2
は有効な式ではないため、コンパイル中にエラーがスローされます。 (詳細は下記)
次の方法で、stringでoperator +関数を使用できます。
s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
なぜ2がoperator+
でchar
に自動的にキャストされないのか心配な人のために、
template <typename CharT>
basic_string<CharT>
operator+(const basic_string<CharT>& lhs, CharT rhs);
上記はプロトタイプです[注意] s + 2
のプラス演算子の場合、およびテンプレート関数であるため、operator+<char>
とoperator+<int>
の両方の実装が必要です。これは競合しています。詳細については、「 自動ダウンキャストがテンプレート関数に適用されないのはなぜですか? 」を参照してください
一方、operator+=
のプロトタイプは次のとおりです。
template <typename CharT>
class basic_string{
basic_string&
operator+=(CharT _c);
};
ここにテンプレートはありません(クラスメンバー関数です)。したがって、コンパイラは、CharT型がクラス実装からchar
であると推測し、int(2)
はchar(2)
に自動的にキャストされます。
注意: C++標準インクルードソースからコピーすると、不要なコードが削除されます。これには、読みやすくするために、テンプレートクラス「basic_string」のtypename 2および3(TraitsおよびAllocator)、および不要なアンダースコアが含まれます。
s += 2;
は、あなたが思っていることをしていない。オーバーロードされた+=
演算子をchar
に呼び出します。 notはcharacter'2'
を追加しますが、value2の文字を追加します、結果はプラットフォームで使用されるencodingに依存します。
s + 2
のコンパイルを許可するために定義された演算子オーバーロードはありません1。したがって、エラー。
両方の場合の解決策は、int
リテラル2ではなくstd::to_string(2)
を使用することです。
1 本質的には、operator+=
はテンプレート関数ではなく、std::operator+
はテンプレート関数であり、オーバーロード解決はテンプレート関数よりも非テンプレート関数を優先するためです。
string
に追加する正しい方法は
std::string s;
s += std::to_string(2);
s = s + std::to_string(2);
@CoryKramerの答えは、文字列に整数を追加する正しい方法を提供しますが、命令s = s + 2
がコンパイルされない理由を説明しません。
2つの命令の違いは、最初の命令ではstd::string
の- + =演算子 を使用しますが、2番目の命令では、コンパイラが2
を文字列。
int
とstd::string
の間に暗黙的な変換はありません。ただし、int
をchar
にキャストできるため、s += 2
worksが機能するのはこのためです。