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




Наилучшая из устоявших функция - часть 4


Вот еще пример, в котором приведение спецификаторов влияет на то, какая последовательность будет выбрана:

int extract( void * );

int extract( const void * );

int* pi;

int main() {

   extract( pi );  // выбирается extract( void * )

   return 0;

}

Здесь для вызова есть две устоявших функции: extract(void*) и extract(const void*). Последовательность преобразований для функции extract(void*) состоит из трансформации l-значения в r-значение для извлечения значения аргумента, сопровождаемого стандартным преобразованием указателя: из указателя на int в указатель на void. Для функции extract(const void*) такая последовательность отличается от первой дополнительным преобразованием спецификаторов для приведения типа результата от указателя на void к указателю на const void. Поскольку последовательности различаются лишь этой трансформацией, то первая выбирается как более подходящая и, следовательно, наилучшей из устоявших будет функция extract(const void*).

Спецификаторы const и volatile влияют также на ранжирование инициализации параметров-ссылок. Если две такие инициализации отличаются только добавлением спецификатора const и volatile, то инициализация без дополнительной спецификации считается лучшей при разрешении перегрузки:

#include <vector>

void manip( vector<int> & );

void manip( const vector<int> & );

vector<int> f();

extern vector<int> vec;

int main() {

   manip( vec );   // выбирается manip( vector<int> & )

   manip( f() );   // выбирается manip( const vector<int> & )

   return 0;

}

В первом вызове инициализация ссылок для вызова любой функции является точным соответствием. Но этот вызов все же не будет неоднозначным. Так как обе инициализации одинаковы во всем, кроме наличия дополнительной спецификации const во втором случае, то инициализация без такой спецификации считается лучше, поэтому перегрузка будет разрешена в пользу устоявшей функции manip(vector<int>&).




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