Приведение типов и указатели
1) Почему не компилируется следующий код:
int *i;
void*& RefPtr = (void*)i;
Создается временная non-lvalue переменная?
2) Почему, например, int** не приводится к void** неявно?
Используемы компиляторы: gcc, VS 6.0.
Цитата: Игорь В.
Два вопроса по приведению типов:
1) Почему не компилируется следующий код:
int *i;
void*& RefPtr = (void*)i;
Создается временная non-lvalue переменная?
2) Почему, например, int** не приводится к void** неявно?
Используемы компиляторы: gcc, VS 6.0.
1) Почему не компилируется следующий код:
int *i;
void*& RefPtr = (void*)i;
Создается временная non-lvalue переменная?
2) Почему, например, int** не приводится к void** неявно?
Используемы компиляторы: gcc, VS 6.0.
1. Потому что по сути пытаются привести указатель на тип к указателю на ссылку. Кстати билдер это откомпилировал без проблем. вижуал отказался, что вобщем то верно.
2. Зачем?
Код:
int &n=10;
и чем это отличается от
Код:
int n=10;
И зачем вообще использовать амперсанд в описании переменных (слева).
Код:
int *i;
void *& RefPtr = reinterpret_cast<void *&> (i);
void *& RefPtr = reinterpret_cast<void *&> (i);
Я вообщем то, понимаю, что любой код имеет право на существование... но интересно, правда, зачем это конструкция? Указатели на ссылки запрещены...
Цитата: Hydra
А кто-нть может сказать, что вообще может означать
и чем это отличается от
И зачем вообще использовать амперсанд в описании переменных (слева).
Код:
int &n=10;
и чем это отличается от
Код:
int n=10;
И зачем вообще использовать амперсанд в описании переменных (слева).
Не очень понятен вопрос. Что такое ссылка известно?
Хотя в приведенном коде правильней было бы так:
Код:
int n=10;
int &reff = n;
int &reff = n;
объявлена переменная целого типа и объявлена ссылка на нее.
Но раз возникли недоразумения, приведу еще один пример:
typedef void* VoidPtr;
void Test(VoidPtr &)
{}
int main(int argc, char* argv[])
{
int i = 0;
int *iPtr = &i;
Test((VoidPtr)iPtr);
return 0;
}
Вот этот код также не компилируется. Компилируется только если я явно привожу iPtr к ссылке при вызове Test. То-есть:
Test((VoidPtr&)iPtr);
Также компилируется, если Test вызыввается без приведения типов:
void *vPtr = i;
Test(vPtr);
Я интересовался этим вопросом на работе. Мало кто смог более-менее внятно объяснить, в чем здесь дело. На сколько я понял, после приведения типа объект перестает быть lvalue. Некоторые еще утверждают, что при приведении типов создается временный объект.
Хотелось бы услышать более информативный ответ. В частности, если временный объект создается, то: всегда ли при приведении типов? как это происходит? и т.д.
Также буду благодарен, если посоветуете хорошее описание работы компилятора С++. Меня не интересуют мелкие детали, зависящие от реализации. Просто хотелось бы знать основные принципы.
Что касается моего второго вопроса - "Почему, например, int** не приводится к void** неявно?" - то мне часто приходится делать такое приведение при работе с Carbon framework (Mac OSX).
Вообщем да, ваши коллеги правы (причем и те и другие).
И так имеем.
Test((VoidPtr)iPtr) - не lvalue.
Test((VoidPtr&)iPtr) - lvalue.
Дело в том, что преобразования не к ссылочным типам считается rvalue. Соотвественно поэтому ошибка.
Про определенние rvalue и lvalue (и еще много про что) - здесь.
//==== Add
Так как ссылка по сути является константным указателем, то иннициализироваться она может только один раз, при объявлении. Иннициализация разрешена только lvalue (объектом имеющим адрес в памяти).
И насчет первого вашего примера.
Код:
typedef int* VoidPtr;
void Test(VoidPtr &)
{}
int main(int argc, char* argv[])
{
int i = 0;
int *iPtr = &i;
int *& RefPtr = iPtr; // корректно
Test((VoidPtr)iPtr); // не корректно
return 0;
}
void Test(VoidPtr &)
{}
int main(int argc, char* argv[])
{
int i = 0;
int *iPtr = &i;
int *& RefPtr = iPtr; // корректно
Test((VoidPtr)iPtr); // не корректно
return 0;
}
Рекомндую всем!