Подтвердить что ты не робот

С++, Need Причина ошибки: невозможно преобразовать параметр 1 из 'char *' в 'const char * &'

Whey мы не можем преобразовать указатель на символ → TO- > ссылку на указатель на постоянный символ

Мне интересно узнать причину синтаксической ошибки, когда мы вызываем foo_ptr. Когда foo_char разрешен, почему не foo_ptr.
[Обновление 1.] Я был бы рад узнать причину, по которой работает foo_char(), почему foo_ptr() не работает. Что происходит, когда указатель появляется на картинке.

[Обновление 2.] Не работал в компиляторе Dev С++ версии 4.9.9.2 тоже..

//code
//OS : Win XP
//Env: VC++ 2008 

//NOT ALLOWED
void foo_ptr(const char * & ptr) //reference to a pointer to a constant character         
{         
        return;         
}        


//allowed        
void foo_char(const char & p_Char) //reference to a constant character        
{         
        return;        
}        

int main()        
{        
        char ch = 'd';        
        char *ptr =  "anu";        

        foo_char(ch);         
        foo_ptr(ptr); //NOT ALLOWED syntax error, vc++, 2008        

        return 0;        
}        
4b9b3361

Ответ 1

Пересмотрено с дополнительными примерами:  Раймонд Чен дает правильный ответ. Передавая не const-указатель (char *) как ссылочный параметр указателя const (foo_ptr(const char * &param)), вы рискуете вернуть тип указателя const (const char *), и компилятор не позволит вам это сделать.

Здесь Raymond Chen пример, но я попытался объяснить, как все пойдет не так, если он скомпилирован, добавив дополнительные комментарии и код:

void foo_ptr(const char * & ptr)
{         
    //Valid assignment, and the char * is now pointing to a const
    //array of "readonlystring"
    ptr = "readonlystring";
}   

...
//inside main
char *ptr = malloc(10*sizeof(char));
//See you can edit ptr, it not const.
ptr[0] = 'a';
ptr[1] = 'b';
//this should not compile, but lets assume it did..
foo_ptr(ptr);
//Oh no, now ptr[0] is 'r' inside of constant memory,
//but now since ptr isn't declared const here I can overwrite it!
//But luckily most (all?) compilers actually fail to compile this code.
ptr[0] = 'b';

Но если вы измените свой параметр, чтобы не влиять на значение, на которое указывает указатель, тогда компилятор будет пропускать вас в не-const, потому что нет шанса на возврат указателя на константу.

Поместив ключевое слово const ПОСЛЕ * в замедление параметров, вы сделаете именно это. Это означает изменение:

void foo_ptr(const char * & ptr)

to

void foo_ptr(const char * const & ptr)

и ваш компилятор будет счастлив.

Теперь вы не сможете сделать что-то вроде ptr = "readonlystring" в приведенном выше примере, потому что это никогда не будет компилироваться. Исходя из вашего вопроса, который должен быть в порядке, потому что вы не сможете выполнить назначение const char & в вашем исходном примере.

Ответ 2

Предположим, что у вас был

void foo_ptr(const char * & ptr)
{         
    ptr = "readonlystring";
}        

Теперь вы называете это

    char *ptr;
    foo_ptr(ptr);
    *ptr = 0;

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

В основном это CV-версия Почему указатель на производный класс не может быть передан функции, ожидающей ссылки на указатель на базовый класс?.

Ответ 3

Вы не должны присваивать строковый литерал указателю не const char, как вы здесь:

 char *ptr =  "anu";        

Измените приведенное выше, чтобы исправить код:

 const char *ptr =  "anu";        

... и я думаю, вы обнаружите, что ваши проблемы решены.