2013-10-07 3 views
0

Я хочу написать функцию, которая изменяет данный указатель любого типа; таким образом, я объявил свою функцию принять void*&, полагаясь на неявное преобразование с любого указателя на void*. Однако следующий код отказывается компилировать, заявив, что он не может преобразовать int* в void*&.Неявное преобразование типов со ссылкой на void *

void f(void*& x) 
{ 
    x = 0; 
} 

int main() { 

    int* a = new int; 
    f(a); 
    delete a; 
    return 0; 
} 

Обратите внимание, что он работает нормально, если е объявлен прием int*& (но затем теряет свою всеобщность), или если е объявлен как приняв void* (но е может только изменить свой аргумент локально).

Так самостоятельно «любое T* к void*» правилам преобразования неявного работает, неявное правило преобразования "T в T& работает, но не оба одновременно? Почему это так? Что я здесь не так?

(Я знаю, что я мог бы использовать функцию шаблона для f, это в основном из любопытства).

+0

http://stackoverflow.com/questions/399003/is-the-sizeofsome-pointer-always-equal-to-four "не гарантирует, что sizeof (int *) == sizeof (double *)" - так что есть никоим образом не генерировать не-шаблонный код, который делает то, что вы хотите. –

+0

@KarolyHorvath: 'void *' всегда достаточно велик, чтобы удерживать указатель объекта. Это также спорно, если это возможно разница в размерах (что нигде не видело в реальных внедрениях кстати.) Объектные указатели реально и предназначено, или просто придирчивый интерпретация рассеянных стандартных формулировок. – PlasmaHH

+0

@PlasmaHH: Я не уверен, что вы намеревались передать с этим ... должен ли код только нулевое местоположение памяти для void * (что достаточно большой), потенциально переписывая расположение памяти другой переменной? –

ответ

2

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

Это, конечно, может быть решена с помощью шаблонов:

template<typename T> 
void f(T*& x) { ... } 
0

Если бы здесь работать, вы бы создать временный void* из-за T* (поскольку преобразование здесь на самом деле означает «создать новый объект другого типа») который затем будет привязывать ссылку, которая не будет работать, поскольку она не является константой. Что бы работать, хотя это:

void f(void* const & x) 
{ 
    x = 0; 
} 

Но это, вероятно, не то, что вы хотели, так как он имеет в виду временное, а не int*.

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