Я проиллюстрирую свой вопрос с кодом:
#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 из 'неподписанного символа *' к 'константе неподписанный символ *&'. Если я некомментирую, что "константа" комментирует, что хорошо работает.
Однако разве указатель не должен неявно преобразовывать в указатель константы и затем ссылку быть взятым? Я нахожусь неправильно в ожидании, что это работает?Спасибо!
Если указатель преобразуется в константный указатель, как вы предлагаете, то результатом этого преобразования является временное значение, 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`
код будет компилироваться.
Думаю, вам понадобится:
void PrintInt (const unsigned char * const & ptr)
, если вы хотите передать константный указатель по ссылке.
Это нарушит корректность констант:
// 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
одинаковы, он будет изменять константу.