Ошибка: недопустимые операнды типов 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>");