Проблемы с передачей аргумента в параметр const - PullRequest
2 голосов
/ 18 декабря 2009

Скажем, у меня есть функция, которая принимает константную ссылку на указатель ...

Пример:

void Foo( const Bar *&p_Thing, );

и я передаю указатель

Bar *blah = NULL; // Initialized when program starts up

к функции

Foo( blah );

Я могу столкнуться с ошибкой компилятора, подобной этой

invalid initialization of reference of type 'const Bar*&' from expression of type 'Bar*'

Это случалось со мной несколько раз, и я действительно хотел бы прояснить, как работает const с точки зрения применения к параметрам в отношении передачи аргументов. Любая помощь приветствуется, спасибо.

Ответы [ 6 ]

2 голосов
/ 18 декабря 2009

Это то, что вы хотите:

void Foo( Bar * const &p_Thing );

Затем он становится константной ссылкой на указатель Bar *, который обладает прекрасной возможностью компиляции.

0 голосов
/ 18 декабря 2009

В то время как большинство вопросов отвечают на вопрос (вы не можете передать мутирующий указатель по ссылке в функцию, которая принимает не мутирующий указатель по ссылке), я не думаю, что логическое обоснование делается явным в любом из ответов:

Это нарушило бы правильность. Если вы передадите не мутирующий указатель по ссылке на функцию, принимающую постоянный указатель по ссылке, он вполне может изменить указатель для ссылки на постоянный объект (в конце концов, тип гарантирует, что он не изменит это значение). Теперь проблема в том, что вне вашей функции переданный указатель на самом деле не является константным, и компилятор должен был бы разрешить любую операцию мутации с указанным объектом, что подразумевало бы изменение объекта, который изначально был константой.

Вот краткий пример:

const int y = 0;
void f( const int *& p ) {
   p = &y; // ok, p is a pointer to a constant integer
}
int main()
{
   int *p;
   f( p ); // if this was allowed p would point to y, but y is constant
   *p = 5; // correct, p is a mutating pointer
}
0 голосов
/ 18 декабря 2009

Ваша функция требует указатель до постоянные данные .

Вы передаете указатель на изменяемые или непостоянные данные. Некоторые компиляторы могут жаловаться на const целевые данные.

0 голосов
/ 18 декабря 2009

Ответ в этом конкретном случае прост: операция ожидает ссылку на указатель на постоянную память, но вы передаете ему указатель на неконстантную память. Создание бла константного бара * позволило бы это.

Однако вы должны рассмотреть эту схему прохождения, если у вас проблемы с указателями и константностью. Передача указателя по ссылке не редкость, но для 90% задач это на самом деле не нужно. Вместо этого вы можете передать указатель или ссылку или вернуть его в качестве значения вызова функции или метода. Это было бы проще с точки зрения управления памятью и разборчивости вашего кода.

0 голосов
/ 18 декабря 2009

Я никогда не мог понять синтаксическую разницу между указателями на ссылки и ссылками на указатели. Поэтому я однозначно:

typedef const Bar *PBar;
void Foo(const PBar &p_Thing);

Таким образом, вы также избавляетесь от неоднозначности «указатель констант» / «указатель на констант».

0 голосов
/ 18 декабря 2009

Полагаю, вы хотите постоянную ссылку на Bar *, а не ссылку на const Bar *? Если да, вы хотите определить его как void Foo (Bar * const & p)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...