неверная инициализация неконстантной ссылки типа ‘const char * & amp;’ из значения типа ‘const char *’

я сделал функцию mystrcpy,

void mystrcpy(char *&stuff, const char *&otherstuff){
for(int i=0; stuff[i]&&other[i]; i++){
stuff[i]=other[i];
}
}

и основная функция:

int main(){
char *hello="hello";
mystrcpy(hello, "bye bye"/*<--i have no clue what data type this really is!!*/);
printf("%s\n", hello);
return 0;
}

он не компилируется и говорит «неверная инициализация неконстантной ссылки типа» const char *&’из значения типа’ const char * ‘»…

когда я просто делаю:

const char *bye="bye bye";
mystrcpy(hello, bye);

компилируется без ошибок.

Мне нужно знать, почему первый не работает, спасибо.

0

Решение

Ваша функция занимает ссылка на указатель, что немного необычно. В частности, это означает, что входные данные должны быть указателем, который имеет свое собственное хранилище (чтобы вы могли взять ссылку на указатель).

const char *bye="bye bye"; mystrcpy(hello, bye); работает потому что bye является переменной указателя, так что вы можете взять ссылку на нее.

mystrcpy(hello, "bye bye") не удается, потому что "bye bye" является не указатель — это массив символов ( const char [8]) и поэтому нет указателя для ссылки.

Вам не нужна ссылка & в вашем mystrcpy сигнатура функции — это просто усложняет использование функции и может привести к появлению интересных ошибок, если вы случайно отрегулируете указатели в функции (например, если вы начали делать *stuff++ = *other++;).

1

Другие решения

const char *& это неconst ссылка на char const *, Тип "bye bye" является char const[8] (размер включает в себя завершающий нулевой символ). Ваш звонок в mystrcpy будет неявное преобразование (или распад) char const [8] к char const *, но это создает указатель rvalue, который вы не можете привязать кconst эталонный параметр.

Если вы измените свою подпись функции на

void mystrcpy(char *&, const char * const&)
//                                  ^^^^^ const reference

ваш код скомпилируется. Точно так же, если вы возьмете указатель (и) по значению, ваш код скомпилируется

void mystrcpy(char *, const char *)

Как только вы исправите все это, ваш код будет скомпилирован и, возможно, потерпит крах во время выполнения, потому что у вас неопределенное поведение.

char *hello="hello";

C ++ 11 запрещает вам преобразовывать строковый литерал в char *и было объявлено устаревшим поведение в C ++ 03. Не только это, но ваш mystrcpy Затем call пытается перезаписать строковый литерал, что снова является неопределенным поведением.

Увеличьте уровень предупреждений вашего компилятора и обратите внимание на предупреждения. g ++ выдает следующее предупреждение для строки выше с -pedantic

предупреждение: ISO C ++ запрещает преобразовывать строковую константу в ‘char *’ [-Wpedantic]

 char *hello="hello";
^
2

«пока» не указатель, а массив символов. Он может распадаться на указатель, но невозможно передать его как ссылку на указатель.

Вы можете изменить сигнатуру функции:

void mystrcpy(char *stuff, const char *otherstuff)

Если вы хотите проверить тип во время компиляции, вы можете использовать статическое утверждение, генерирующее ошибку компилятора:

#include <type_traits>

template <typename T>
void inspect_type(T&)
{
static_assert(std::is_same<T, void>::value, "inspect_type");
}

int main()
{
inspect_type("bye bye");
}

g ++ дает:

В экземпляре ‘void inspect_type (const T&) [с T = const char [8]] ’

2
По вопросам рекламы [email protected]