Странный символ * ошибка компиляции? - PullRequest
3 голосов
/ 15 февраля 2009

Что-то не так с моим кодом ниже? Я получил ошибку компиляции!

typedef unsigned char BYTE;

void foo(char* & p)
{
 return;
}

int main()
{
  BYTE * buffer;
  // error C2664: 'foo' : cannot convert parameter 1 from 'char *' to 'char *&'
  foo ((char*)buffer);

  return 0;
}

Спасибо заранее, George

Ответы [ 7 ]

14 голосов
/ 15 февраля 2009

Когда вы приводите BYTE* к char*, создается неназванная временная сущность с типом char*. Вызываемая функция берет ссылку на char*, но вы не можете взять ссылку на такую ​​временную сущность, потому что она не является реальной переменной.

7 голосов
/ 15 февраля 2009

Вы можете выполнить reinterpret_cast<char*&> вместо статического приведения

foo (reinterpret_cast<char*&>(buffer));

Или вы можете сделать аргумент константной ссылкой:

void foo(char* const & p)
{
    return;
}
4 голосов
/ 15 февраля 2009

Параметр foo является ссылкой на указатель. буфер является указателем BYTE. Ссылка требует точного соответствия, совместимость с назначением не подходит.

Два решения:

1) вам, вероятно, не нужно '&' перед p. Потеряй его и код скомпилируется.

2) Используйте правильно введенную переменную, чтобы ссылка работала:

 BYTE * buffer;
 char * b = (char *) buffer;
 foo (b);
 buffer = (BYTE*) b;  // because foo may change b
2 голосов
/ 15 февраля 2009

Указатель buffer является "lvalue", но когда к нему применяется операция приведения, выражение:

(char*) buffer

- это «значение» (на самом деле «изменяемое значение» - но я думаю, что это имеет значение только в грядущем C ++ 0x). Неконстантные ссылки не могут быть привязаны к значениям.

Однако, const ссылки могут быть связаны с rvalues. Поэтому следующая модификация вашей программы будет скомпилирована:

void foo(char* const& p)  // added 'const'

Стефан Т. Лававей недавно опубликовал запись в блоге, в которой содержится отличная информация о lvalues, rvalues ​​и ссылках:

В действительности статья посвящена новым «ссылкам на rvalue», появившимся в C ++ 0x, но в ней дано прекрасное объяснение того, что такое lvalues ​​и rvalue, и как они могут и не могут работать со ссылками в C ++ 98. Это долгое чтение, но оно того стоит.

1 голос
/ 15 февраля 2009

Напишите так:

int main() { 
  BYTE * buffer; 
  char* pbuf = (char*)buffer;
  foo(pbuf);
}
1 голос
/ 15 февраля 2009

Во-первых, когда вы говорите

(char)buffer

Вы лжете компилятору - буфер это указатель, а не символ.

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

Итак, да, в вашем коде есть как минимум две вещи.

1 голос
/ 15 февраля 2009

Вы пытаетесь передать ссылку на переменную, но нет такой переменной типа char *, на которую вы могли бы сослаться.

Это должно работать так, если я правильно помню:

BYTE * buffer;
char* ptr = (char*)buffer;
foo(ptr); // now you have a matching variable to refer to. 

Может быть, было бы проще просто передать значение вместо ссылки.

...