Ошибка: недопустимые операнды типов const char [35] и 'const char [2] для двоичного' оператора +

В верхней части моего файла у меня есть

#define AGE "42"

Позже в файле я использую ID несколько раз, включая некоторые строки, которые выглядят как

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

Я получаю сообщение об ошибке:

": недопустимые операнды типов" const char [35] и 'const char [2] для двоичного' оператора + "

в строке 3. Я провел некоторое исследование и нашел, что это связано с тем, как С++ обрабатывал разные строки и смог исправить его, изменив "AGE" на "string (AGE)". Тем не менее, я случайно пропустил один из экземпляров до сегодняшнего дня и задавался вопросом, почему компилятор не жаловался, хотя у меня все еще был экземпляр, где он был просто "ВОЗРАСТ".

Через некоторые пробные и ошибки я обнаружил, что мне нужно только string(AGE) в строках, где я не конкатенирую другую строку, созданную в теле функции.

Мои вопросы: "Что происходит в фоновом режиме, что С++ не любит конкатенировать строку со строкой, помещенной там препроцессором, если вы также не объединяете строку, определенную вами в функции".

Ответ 1

Рассмотрим это:

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

Оба параметра rhs и lhs для operator + равны char* s. Не существует определения operator +, которое принимает два char* (на самом деле язык не позволяет вам написать один). В результате на моем компиляторе возникает ошибка "не может добавить двух указателей" (ваши, по-видимому, выражают вещи в терминах массивов, но это та же проблема).

Теперь рассмотрим следующее:

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

Существует определение operator +, которое принимает a const char* как lhs и a std::string как rhs, поэтому теперь все счастливы.

Вы можете продлить это до цепочки конкатенаций, сколько захотите. Тем не менее, это может стать беспорядочным. Например:

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*), который определен в стандартной библиотеке. Замена этих двух операндов их результатом дает:

((string) + char*)

Это именно то, что мы только что сделали, и которое по-прежнему является законным. Но попробуйте одно и то же:

((char* + char*) + string)

И вы застреваете, потому что первая операция пытается добавить два char* s.

Мораль истории: если вы хотите убедиться, что цепь конкатенации будет работать, просто убедитесь, что один из первых двух аргументов явно имеет тип std::string.

Ответ 2

AGE определяется как "42", поэтому строка:

str += "Do you feel " + AGE + " years old?";

преобразуется в:

str += "Do you feel " + "42" + " years old?";

Это неверно, так как "Do you feel " и "42" являются const char[]. Чтобы решить эту проблему, вы можете сделать один a std::string или просто удалить +:

// 1.
str += std::string("Do you feel ") + AGE + " years old?";

// 2.
str += "Do you feel " AGE " years old?";

Ответ 3

В строке 2 присутствует std::string (name). Существуют операции, определенные для char[] + std::string, std::string + char[] и т.д. "Hello " + name дает std::string, который добавляется к " you are ", указывая другую строку и т.д.

В строке 3 вы говорите

char[] + char[] + char[]

и вы не можете просто добавлять массивы друг к другу.

Ответ 4

Вы не можете конкатенировать необработанные строки, подобные этому. operator+ работает только с двумя объектами std::string или с одним std::string и одной необработанной строкой (по обе стороны операции).

std::string s("...");
s + s; // OK
s + "x"; // OK
"x" + s; // OK
"x" + "x" // error

Самое простое решение - сначала включить исходную строку в std::string:

"Do you feel " + std::string(AGE) + " years old?";

Конечно, вы не должны использовать макрос в первую очередь. С++ не C. Используйте const или, в С++ 11 с надлежащей поддержкой компилятора, constexpr.

Ответ 5

У меня была такая же проблема в моем коде. Я конкатенировал строку для создания строки. Ниже приведена часть кода.

int scannerId = 1;
std:strring testValue;
strInXml = std::string(std::string("<inArgs>" \
                        "<scannerID>" + scannerId) + std::string("</scannerID>" \
                        "<cmdArgs>" \
                        "<arg-string>" + testValue) + "</arg-string>" \
                        "<arg-bool>FALSE</arg-bool>" \
                        "<arg-bool>FALSE</arg-bool>" \
                        "</cmdArgs>"\
                        "</inArgs>");