#c #string #stl
#c #строка #stl
Вопрос:
У меня есть этот код ниже, и я получаю ошибку при компиляции:
error: cannot convert 'const char*' to 'std::string*' for argument '1' to 'void sillyFunction(std::string*, int)'
#include <iostream>
#include <string>
using namespace std;
int counter = 0;
void sillyFunction(string * str, int cool=0);
int main(){
sillyFunction("Cool");
sillyFunction("Cooler", 1);
return 0;
}
void sillyFunction(string * str, int cool){
counter ;
if (cool){
for (int i=0; i<counter; i ) cout << *str << endl;
} else {
cout << *str << endl;
}
}
Ответ №1:
Не принимайте ваш параметр в качестве string *
попробуйте просто использовать const string amp;
вместо
Редактировать:
std::string
и const char*
— это разные типы. std::string
уже выполнено преобразование из строковых литералов (например: "Cool"
) в фактический объект string. Таким образом, передавая строковый литерал, "Cool"
вы в некотором смысле передаете std::string
объект, а не указатель на него.
Причина, по которой я решил использовать const string amp;
, в основном из личных практик кодирования. Это сводит к минимуму использование памяти стека, и поскольку вы передаете постоянный строковый литерал, нет необходимости в том, чтобы параметр мог изменяться.
Также не забывайте, что при переходе с a string *
вам больше не нужно разыменовывать его в вашем cout
:
if (cool){
for (int i=0; i<counter; i ) cout << str << endl;
} else {
cout << str << endl;
}
Комментарии:
1. Если вы подробно изложите свой ответ и объясните, почему он должен это сделать, я поддержу ваш ответ.
Ответ №2:
Чтобы объяснить, в чем на самом деле заключается проблема…
Хотя компилятор с радостью организует «преобразование» char *
/ C-string в std::string
с помощью соответствующего std::string
конструктора, это не то, о чем вы просили.
Вы запросили указатель на существующий std::string
объект. По определению, то, что передается вашей функции, должно быть адресом уже существующего std::string
(или дочернего) объекта.
Вы должны понимать указатели как отдельный тип — ваша функция принимает pointer-to-std::string
«объект». Хотя к a std::string
можно получить доступ через указатель на std::string
, сам указатель не является std::string
, и его нельзя «преобразовать» в a std::string
, и его нельзя рассматривать как указатель на char (или наоборот).
Самой простой альтернативой действительно является постоянная ссылка на std::string
( const std::string amp;
). const , в данном случае, потому что вы ничего не делаете для изменения строки. Если бы это было так, это было бы другое дело, и вам пришлось бы тщательно обдумать, хотите ли вы, чтобы вызывающий объект увидел ваши изменения.
Делая это, вы говорите, что вам нужен std::string
объект (помните, что ссылка на объект является этим объектом, см., в частности, C FAQ 8.5), что позволяет компилятору вызывать соответствующий конструктор для создания std::string для вас, когда функция вызывается с char *
(const или нет).
В то же время, если кто-то передаст вам фактический std::string
параметр, конструктора не будет, и вы получите такую же эффективность, как если бы вы использовали pointer-to-std::string
. Беспроигрышный вариант.
В качестве альтернативы, конечно, вы можете просто взять обычный std::string
, но в этом случае вы всегда получаете копию передаваемой строки, будь то C-string или std::string
. Иногда это желательно, иногда нет. В вашем случае вы ничего не делаете, только выводите строку, делая ненужными накладные расходы.
Ответ №3:
изменить
void sillyFunction(string * str, int cool){
counter ;
if (cool){
for (int i = 0; i < counter; i ) cout << *str << endl;
} else {
cout << *str << endl;
}
}
Для
void sillyFunction(const char* str, int cool){
counter ;
if (cool){
for (int i = 0; i<counter; i ) cout << str << endl;
} else {
cout << str << endl;
}
}
Ответ №4:
Вы можете преобразовать из a const char *
в a string
, но не в string *
.
Возможно, вы хотите, чтобы ваш sillyFunction
использовал ссылку const?
void sillyFunction(const string amp;str, int cool){
counter ;
if (cool){
for (int i=0; i<counter; i ) cout << str << endl;
} else {
cout << str << endl;
}
}
Ответ №5:
Должно быть
void sillyFunction(const stringamp; str, int cool=0);
Ответ №6:
Если вы собираетесь использовать указатели для своих функций, вам нужно где-то объявить строки. необходимо выделить память. поэтому либо объявите переменную, либо вызовите new, чтобы создать память для строки.
int main(){
string str = "Cool";
string str2 = "Cooler";
sillyFunction(amp;str);
sillyFunction(amp;str2, 1);
return 0;
}
Ответ №7:
Вы можете достичь этого, изменив прототип на:
void sillyFunction(string const amp;str, int cool=0);
char const *
может быть неявно преобразован во временный std::string
, который, в свою очередь, может быть передан по ссылке ( std::string const amp;
). Нет неявного преобразования в указатель ( std::string *
), вот почему вы получаете ошибку.
Комментарии:
1. Разве это не должно быть
const string amp;str
?2. @ultimatebuster, это то же самое. Это просто вопрос вкуса, как это написать.
Ответ №8:
У меня есть очень простое решение для этого, используя string copy
char s[20] strcpy(s,const char * p);
Тогда у вас есть строка, на которую указывает *p в s… это работает..