C ++ не может конвертировать 'const char *' в 'std :: string *' - PullRequest
8 голосов
/ 13 мая 2011

У меня есть этот код ниже, и я получаю ошибку при компиляции:

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;
    }
}

Ответы [ 8 ]

13 голосов
/ 13 мая 2011

Не воспринимайте ваш параметр как string *, попробуйте просто использовать const string & вместо

EDIT:

std::string и const char* - это разные типы. std::string уже имеет преобразование из строковых литералов (например: "Cool") в фактический строковый объект. Таким образом, передавая строковый литерал "Cool", вы в некотором смысле передаете объект std::string, а не указатель на него.

Причина, по которой я выбрал const string &, в основном связана с практикой личного кодирования. Это минимизирует использование стековой памяти, и, поскольку вы передаете константный строковый литерал, нет необходимости в параметре, допускающем изменение.

Также не забывайте, если вы измените с string *, что вам больше не нужно разыменовывать его в своем cout:

if (cool){
    for (int i=0; i<counter; i++) cout << str << endl;
} else {
    cout << str << endl;
}
3 голосов
/ 13 мая 2011

изменить

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;
    }
}
2 голосов
/ 13 мая 2011

Чтобы объяснить, в чем проблема на самом деле ...

Хотя компилятор с радостью организует преобразование char * / C-строки в std::string через соответствующий конструктор std::string, это не то, что вы просили.

Вы запросили указатель на существующий std::string объект. По определению, то, что передается вашей функции, должно быть адресом уже существующего std::string (или потомка) объекта.

Вы должны понимать указатели как отдельный тип - ваша функция принимает pointer-to-std::string «объект». Хотя к std::string можно получить доступ через указатель на std::string, сам указатель является , а не a std::string, и при этом он не может быть "преобразован" в std::string, и при этом он не может быть обработан в качестве указателя на символ (или наоборот).

Самая простая альтернатива - это константная ссылка на std::string (const std::string &). в данном случае const, потому что вы ничего не делаете для изменения строки. Если бы это было так, это было бы другое дело, и вам пришлось бы тщательно продумать, намерены ли вы, чтобы вызывающий абонент увидел ваши изменения.

Делая это, вы говорите, что хотите получить объект std::string (помните, ссылка на объект - это тот объект , см., В частности, C ++ FAQ 8.5 ), которая позволяет компилятору вызывать соответствующий конструктор для создания для вас std :: string, когда функция вызывается с char * (постоянным или нет).

В то же время, если кто-то передает вам фактический std::string, конструктор избегается, и вы получаете такую ​​же эффективность, как если бы вы взяли pointer-to-std::string. Беспроигрышный.

В качестве альтернативы, конечно, вы можете просто взять std::string, но в этом случае вы всегда получите копию передаваемой строки, будь то C-строка или std::string. Иногда это желательно, иногда нет. В вашем случае вы ничего не делаете, кроме как распечатываете строку, делая ненужные накладные расходы.

1 голос
/ 13 мая 2011

Если вы собираетесь использовать указатели для своих функций, вам нужно где-то объявить строки.память должна быть выделена.поэтому либо объявите переменную, либо вызовите new, чтобы создать память для строки.

int main(){
    string str = "Cool";
    string str2 = "Cooler";
    sillyFunction(&str);
    sillyFunction(&str2, 1);
    return 0;
}
1 голос
/ 13 мая 2011

Должно быть

void sillyFunction(const string& str, int cool=0);
1 голос
/ 13 мая 2011

Вы можете конвертировать из const char * в string, но не в string *.

Возможно, вы хотите, чтобы ваш sillyFunction использовал константную ссылку?

void sillyFunction(const string &str, int cool){
    counter++;
    if (cool){
        for (int i=0; i<counter; i++) cout << str << endl;
    } else {
        cout << str << endl;
    }
}
1 голос
/ 13 мая 2011

Вы можете добиться этого, изменив прототип на:

void sillyFunction(string const &str, int cool=0);

char const * может быть неявно преобразовано во временный std::string, который, в свою очередь, может быть передан по ссылке (std::string const &).Не существует неявного преобразования в указатель (std::string *), поэтому вы получаете ошибку.

0 голосов
/ 04 февраля 2012

я получил очень простое решение для этого, используя строковое копирование

char s [20] strcpy (s, const char * p);

десять вы получили строку pointrd на * pв с ... это работает ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...