почему никакое неявное преобразование от указателя до ссылки на указатель константы

Я проиллюстрирую свой вопрос с кодом:

#include <iostream>

void PrintInt(const unsigned char*& ptr)
{
    int data = 0;
    ::memcpy(&data, ptr, sizeof(data));
    // advance the pointer reference.
    ptr += sizeof(data);
    std::cout << std::hex << data << " " << std::endl;
}

int main(int, char**)
{
    unsigned char buffer[] = { 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, };

    /* const */ unsigned char* ptr = buffer;

    PrintInt(ptr);  // error C2664: ...
    PrintInt(ptr);  // error C2664: ...    

    return 0;
}

Когда я выполняю этот код (в VS2008), я получаю это: ошибка C2664: 'PrintInt': не может преобразовать параметр 1 из 'неподписанного символа *' к 'константе неподписанный символ *&'. Если я некомментирую, что "константа" комментирует, что хорошо работает.

Однако разве указатель не должен неявно преобразовывать в указатель константы и затем ссылку быть взятым? Я нахожусь неправильно в ожидании, что это работает?Спасибо!

9
задан user316606 25 May 2010 в 20:24
поделиться

3 ответа

Если указатель преобразуется в константный указатель, как вы предлагаете, то результатом этого преобразования является временное значение, rvalue . Вы не можете прикрепить неконстантную ссылку к rvalue - это запрещено в C ++.

Например, этот код не будет компилироваться по той же причине

int i = 42;
double &r = i;

Несмотря на то, что тип int можно преобразовать в тип double , это еще не означает, что вы можете прикрепить двойная и ссылка на результат этого преобразования.

Однако ссылка на константу (то есть ссылка на тип ссылки на константу) может быть присоединена к rvalue, что означает, что этот код будет отлично компилироваться

int i = 42;
const double &r = i;

В вашем случае, если вы объявите свою функцию как

void PrintInt(const unsigned char* const& ptr) // note the extra `const`

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

11
ответ дан 4 December 2019 в 11:40
поделиться

Думаю, вам понадобится:

void PrintInt (const unsigned char * const & ptr)

, если вы хотите передать константный указатель по ссылке.

0
ответ дан 4 December 2019 в 11:40
поделиться

Это нарушит корректность констант:

// if it was allowed
const int x = 5;
int *p;
const int*& cp = p; // cp is a ´constant´ alias to p
cp = &x;            // make cp (and p) point to a constant
*p = 7;             // !!!!

Если преобразование разрешено, приведенный выше код будет компилироваться. После инициализации cp с помощью p (запрещено в языке) они становятся псевдонимами. Теперь вы можете использовать cp , чтобы указать на любой константный объект, поскольку это указатель на константный объект . Изменение значения, указанного в p , также является допустимым кодом, поскольку это указатель на неконстантный объект, но поскольку p и cp одинаковы, он будет изменять константу.

7
ответ дан 4 December 2019 в 11:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: