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

       

Преобразования типов аргументов *


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

  • точное соответствие. Тип фактического аргумента точно соответствует типу формального параметра. Например, если в множестве перегруженных функций print() есть такие:
  • void print( unsigned int );

    void print( const char* );

    void print( char );

    то каждый из следующих трех вызовов дает точное соответствие:

    unsigned int a;

    print( 'a' );    // соответствует print( char );

    print( "a" );    // соответствует print( const char* );

    print( a );      // соответствует print( unsigned int );

    • соответствие с

      преобразованием типа. Тип фактического аргумента не соответствует типу формального параметра, но может быть преобразован в него:

    • void ff( char );

      ff( 0 );         // аргумент типа int приводится к типу char

      • отсутствие соответствия. Тип фактического аргумента не может быть приведен к типу формального параметра в объявлении функции, поскольку необходимого преобразования не существует. Для каждого из следующих двух вызовов функции print() соответствия нет:
      • // функции print() объявлены так же, как и выше

        int *ip;

        class SmallInt { /* ... */ };

        SmallInt si;

        print( ip );     // ошибка: нет соответствия

        print( si );     // ошибка: нет соответствия

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

        • преобразование l-значения в r-значение;
        • преобразование массива в указатель;
        • преобразование функции в указатель;
        • преобразования спецификаторов.
        • (Подробнее они рассмотрены ниже.)

          Категория соответствия с преобразованием типа является наиболее сложной. Необходимо рассмотреть несколько видов такого приведения: расширение типов


          (promotions), стандартные преобразования и определенные пользователем преобразования. (Расширения типов и стандартные преобразования изучаются в этой главе. Определенные пользователем преобразования будут представлены позднее, после детального рассмотрения классов; они выполняются конвертером, функцией-членом, которая позволяет определить в классе собственный набор “стандартных” трансформаций. В главе 15 мы познакомимся с такими конвертерами и с тем, как они влияют на разрешение перегрузки функций.)

          При выборе лучшей из устоявших функций для данного вызова компилятор ищет функцию, для которой применяемые к фактическим аргументам преобразования являются “наилучшими”. Преобразования типов ранжируются следующим образом: точное соответствие лучше расширения типа, расширение типа лучше стандартного преобразования, а оно, в свою очередь, лучше определенного пользователем преобразования. Мы еще вернемся к ранжированию в разделе 9.4, а пока на простых примерах покажем, как оно помогает выбрать наиболее подходящую функцию.


          Содержание раздела