2017-08-21 7 views
1

私はstd :: stringの真ん中から3つの文字を連結しています。私がcharでcharを行うと、期待される結果が得られますが、私が1つの式で行うと、私は奇妙な結果を得ます。どうして?1つの式のstd :: string連結が、charとcharとで異なる結果をもたらす理由を教えてください。

#include <string> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    string s1 = "abcdefghijklmnopq"; 
    string s2 = ""; 
    string s3 = ""; 

    s3+=s1[4]; 
    s3+=s1[5]; 
    s3+=s1[6]; 
    cout << s3 << endl; // Expected behaviour 

    s2=s1[4]+s1[5]+s1[6]; 
    cout << s2 << endl; // ????? 
} 
+8

'char's ** not **' std :: string'sを追加しています – WhiZTiM

+0

理由を説明した回答があります。 1つの解決策は、右辺を強制的に 'std :: string'にすることです。これは変換で行うことができます:' s3 + = std :: string(s1 [4])+ s1 [5] + s1 [6 ]; '。これは、右の式が '' std :: string(s1 [4])+ s1 [5])+ s1 [6] 'と書かれているかのように、' + 'グループが左から右へのルールに依存しています。もしあなたがそれに不快なら、あなたは '' s1 [4] + std :: string(s1 [5])+ s1 [6] 'というグループ化に依存しない、やや奇妙な形式で書くことができます。 –

答えて

8

s1[4]+s1[5]+s1[6]ビルトイン+charタイプを使用しています。すべての引数は、intに促進され、式がintタイプです。これがs2に割り当てられると、オーバーロードされた=演算子がcharに呼び出され、割り当て前に式がcharに切り捨てられます。お使いのプラットフォームのcharsignedの場合、の実装がと定義されています。 http://en.cppreference.com/w/cpp/language/implicit_conversionを参照してください。

s3+=s1[4];char引数の場合、std::stringのオーバーロードされた+=演算子を使用します。これはに連結され、charを文字列に連結します。

は最後に以降C++ 14から、あなたは s2 = s1.substr(4, 3);は、この特定のケースで仕事をするだろう)、あなたの救助に来ることができない美しい

s2 = ""s + s1[4] + s1[5] + s1[6]; 

substr場合を使用することができます。 ユーザ定義リテラル""sにC++ 14標準ライブラリで定義されていることに注意してください。

+2

OP *はおそらく 's2 = s1.substr(4,3);を使用したいと考えています。 –

+0

C++は直観に反するので、charsの和はcharではありません。その場合は、連結演算子を使用して、値を追加するのではなく、連結することを明確にする必要があります。文字列に整数を代入することができるという事実はさらに明白ではない。 –

+0

@ManuelPastor:実際には、 'int'は' char'に変換され、オーバーロードされた '='は 'char'に呼び出されます。私は答えにもう少し牛肉を入れました。 – Bathsheba

関連する問題