C не удается преобразовать ‘const char *’ в ‘std:: string *’

#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… это работает..