2009-02-15 2 views
3

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

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; 
} 

Спасибо заранее, Джордж

+0

Я думаю, что ChrisW на самом деле исправил ошибку в вашем коде во время редактирования ... вы выбрали BYTE * для (char) вместо (char *). – UncleZeiv

+0

Не так, вы не можете передавать временную ссылку, отличную от константы, поэтому ошибка все еще существует: приведение создает временное и которое не может быть передано по ссылке. –

+0

@UncleZeiv История изменений говорит, что я сделал, но я не помню, как это делалось. Я не могу это объяснить. Может быть, кто-то еще, OP даже, делает параллельное редактирование? – ChrisW

ответ

14

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

+0

Не могли бы вы показать мне, как вы его исправите? – George2

+0

Я не уверен в этом ... это указатель, вы просто говорите компилятору, что доверяете вам ... Я почти уверен, что здесь нет никакого временного участия. – UncleZeiv

+0

Исправление зависит от того, что вы хотите сделать и почему эта функция принимает ссылку на указатель. @UncleZeiv - Нет ложки. – shoosh

1

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

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

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

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

+0

Это работает, но почему временная переменная не работает? – George2

+0

Потому что вы хотите передать ссылку. И вы не можете ссылаться на переменную, которая не существует. Поэтому вам нужно создать его. Но я думаю, что ссылка здесь не нужна. Почему бы просто не передать значение? void foo (char * p) –

+0

Может работать не так, как ожидалось: если функция изменяет полученный указатель, изменения будут производиться в ptr var, а не в исходном буфере. –

1

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

(char)buffer 

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

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

Итак, да, в коде есть, по крайней мере, две вещи.

+0

Это не то, что он сказал, он бросает на char *. – flodin

+0

Его сообщение отредактировал – 2009-02-15 19:08:42

1

Написать это так:

int main() { 
    BYTE * buffer; 
    char* pbuf = (char*)buffer; 
    foo(pbuf); 
} 
+0

Если f() изменяет полученный указатель, это изменение применимо к pbuf, а не к буферу. –

4

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

Два решения:

1) Вы, вероятно, не нужен '&' перед р. Освободите его, и код будет скомпилирован.

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

BYTE * buffer; 
char * b = (char *) buffer; 
foo (b); 
buffer = (BYTE*) b; // because foo may change b 
+0

Предполагая, что побочный эффект foo заключается в изменении переданного параметра, вам лучше также делать «buffer = (BYTE *) b;» после вызова foo. – ChrisW

+0

@ChrisW: вы правы, я отредактирую его. Делает вопрос об исправлении ошибок. –

7

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

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

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

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

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

(char*) buffer 

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

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

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

Стефан Т. Lavavej недавно опубликовал запись в блоге, который имеет большую информацию о lvalues, rvalues ​​и ссылки:

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

Смежные вопросы