1. ホーム
  2. c++

エラー: バイナリ 'operator+' へのオペランド 'const char [35]' および 'const char [2]' の型が無効です。

2023-09-08 13:01:40

質問

私のファイルの先頭には

#define AGE "42"

このファイルの後半では、ID を複数回使用しており、次のような行もあります。

std::string name = "Obama";
std::string str = "Hello " + name + " you are " + AGE + " years old!";
str += "Do you feel " + AGE + " years old?";

エラーが出ます。

error: invalid operands of types 'const char [35]' and 'const char [2]' to binary 'operator+'"

というエラーが3行目に出ています。調べてみると、C++ が異なる文字列をどのように扱っているかが原因であることがわかり、"AGE" を "string(AGE)." に変えることで修正できました。しかし、今日まで偶然にもインスタンスの 1 つを見逃していたので、まだ "AGE" であるにもかかわらずコンパイラが文句言わないのはどういうことかと思いました。

いくつかの試行錯誤の結果、私が必要とするのは string(AGE) を必要とするのは、関数本体で作成された別の文字列を連結しない行だけであることがわかりました。

私の質問は、quot;C++がプリプロセッサによって置かれた文字列と文字列を連結することを嫌う背景には何があるのか、関数内で定義した文字列も連結しているのでなければ。

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

これを考えてみましょう。

std::string str = "Hello " + "world"; // bad!

のrhsとlhsはともに operator +char* s. の定義はありません。 operator + を2つ取るような定義はありません。 char* を2つ取ることができます(実際、この言語は1つを書くことを許可していません)。その結果、私のコンパイラーでは、これは "cannot add two pointers" エラーを発生させます (あなたのコンパイラーはどうやら配列の用語で物事を表現しているようですが、同じ問題です)。

では、これを考えてみましょう。

std::string str = "Hello " + std::string("world"); // ok

そこで の定義があります。 operator + を取るもので const char* をlhsとし std::string を右辺とすると、これでみんなハッピーです。

これを好きなだけ長い連結鎖に拡張することができます。しかし、面倒になることもある。例えば

std::string str = "Hello " + "there " + std::string("world"); // no good!

これはうまくいきません。 + 二つ char* に変換される前に、Lhsが std::string . でもこれでいいんです。

std::string str = std::string("Hello ") + "there " + "world"; // ok

なぜなら、一度変換したものを std::string に変換すると + を追加した数だけ char* を好きなだけ追加できます。

それでもまだ分かりにくい場合は、括弧を追加して連想のルールを強調し、変数名をその型に置き換えるとよいかもしれません。

((std::string("Hello ") + "there ") + "world");
((string + char*) + char*)

最初のステップでは string operator+(string, char*) を呼び出すことです。これは標準ライブラリで定義されています。この2つのオペランドをその結果に置き換えると、次のようになります。

((string) + char*)

これはまさに今やったことであり、まだ合法です。しかし、同じことをで試してみてください。

((char* + char*) + string)

そして、最初の操作で2つの char* s.

この話のモラル。もし連鎖がうまくいくことを確かめたいなら、最初の2つの引数のうち1つが明示的に std::string .