1. ホーム
  2. c++

[解決済み] 2つの文字列リテラルを連結する

2022-08-02 22:05:25

質問

Koenig著のAccelerated C++を読んでいます。彼は、新しい考え方は、文字列と文字列リテラルを連結するために + を使用できること、あるいは、2 つの文字列 (ただし、2 つの文字列リテラルは不可) を連結できることであると書いています。

なるほど、これは理にかなっていますね。では、これを明らかにするための 2 つの別々の演習に移ります。

次の定義は有効ですか?

const string hello = "Hello";

const string message = hello + ",world" + "!";

さて、上記を実行してみたところ、うまくいきました! というわけで、嬉しかったです。

そして、次の練習をしてみました。

const string exclam = "!";

const string message = "Hello" + ",world" + exclam;

これはうまくいきませんでした。今、私はそれがあなたが2つの文字列リテラルを連結することができないという事実と関係があることを理解していますが、私はなぜ私が動作するように最初の例を得ることができたかの意味上の違いを理解していません(",world" と "!" 2文字列リテラルではないでしょうか?これは動作しないはずですか?)、しかし2番目は動作しない。

どのように解決するのですか?

const string message = "Hello" + ",world" + exclam;

+ 演算子は左から右への連想性を持つので、同等の括弧付き表現は次のようになります。

const string message = (("Hello" + ",world") + exclam);

見ての通り、2つの文字列リテラル "Hello"",world" が最初に追加されるため、エラーが発生します。

連結される最初の2つの文字列のうち、1つは std::string オブジェクトでなければなりません。

const string message = string("Hello") + ",world" + exclam;

あるいは、2番目の + を括弧でくくることで、2番目のが最初に評価されるようにすることもできます。

const string message = "Hello" + (",world" + exclam);

最初の例( hello + ",world" + "!" ) が機能するのは std::string ( hello ) は、一番左の + . その + が評価されると、その結果は std::string オブジェクトとなり、その結果得られた std::string に連結されます。 "!" .


については なぜ を使って二つの文字列リテラルを連結することはできません。 + を使うことができないのは、文字列リテラルが単なる文字の配列であるからです (a const char [N] ここで N は文字列の長さに1を足したもので、ヌルターミネータを意味します)。 ほとんどの文脈で配列を使用する場合、配列はその初期要素へのポインタに変換されます。

ですから、あなたが "Hello" + ",world" を行おうとすると、実際に行おうとしていることは、2つの const char* を一緒に追加することですが、これは不可能であり(2 つのポインタを一緒に追加することは何を意味するでしょうか)、もし可能であれば、それはあなたがそれを望んでいたことを実行しないでしょう。


あなたは は、文字列リテラルを隣り合わせにすることで連結することができます。例えば、次の二つは等価です。

"Hello" ",world"
"Hello,world"

これは、長い文字列リテラルを複数行に分割したい場合に便利です。 しかし、それらは文字列リテラルでなければなりません。 const char* のポインタや const char[N] 配列になります。