С++ для начинающих




Ссылки - часть 2


Вот еще один пример, в котором между формальным параметром-ссылкой и фактическим аргументом нет соответствия:

class B;

void takeB( B& );

B giveB();

int main() {

   takeB( giveB() );   // ошибка: параметр должен быть типа const B &

   return 0;

}

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

В обоих случаях мы видим, что если формальный параметр-ссылка имеет спецификатор const, то между ним и фактическим аргументом может быть установлено точное соответствие.

Следует отметить, что и преобразование l-значения в r-значение, и инициализация ссылки считаются точными соответствиями. В данном примере первый вызов функции приводит к ошибке:

void print( int );

void print( int& );

int iobj;

int &ri = iobj;

int main() {

   print( iobj );   // ошибка: неоднозначность

   print( ri );     // ошибка: неоднозначность

   print( 86 );     // правильно: вызывается print( int )

   return 0;

}

Объект iobj – это аргумент, для которого может быть установлено соответствие с обеими функциями print(), то есть вызов неоднозначен. То же относится и к следующей строке, где ссылка ri обозначает объект, соответствующий обеим функциям print(). С третьим вызовом, однако, все в порядке. Для него print(int&) не является устоявшей. Целая константа – это r-значение, так что она не может инициализировать параметр-ссылку. Единственной устоявшей функцией для вызова print(86) является print(int), поэтому она и выбирается при разрешении перегрузки.

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

Упражнение 9.6

Назовите два тривиальных преобразования, допустимых при установлении точного соответствия.

Упражнение 9.7




Содержание  Назад  Вперед