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


Функции-кандидаты


Функцией-кандидатом называется функция, имеющая то же имя, что и вызванная. Кандидаты отыскиваются двумя способами:

  • объявление функции видимо в точке вызова. В следующем примере
  • void f();

    void f( int );

    void f( double, double = 3.4 );

    void f( char*, char* );

    int main() {

       f( 5.6 );   // для разрешения этого вызова есть четыре кандидата

       return 0;

    }

    все четыре функции f() удовлетворяют этому условию. Поэтому множество кандидатов содержит четыре элемента;

    • если тип фактического аргумента объявлен внутри некоторого пространства имен, то функции-члены этого пространства, имеющие то же имя, что и вызванная функция, добавляются в множество кандидатов:
    • namespace NS {

         class C { /* ... */ };

         void takeC( C& );



      }

      // тип cobj - это класс C, объявленный в пространстве имен NS

      NS::C obj;

      int main() {

                       // в точке вызова не видна ни одна из функций takeC()

         takeC( cobj); // правильно: вызывается NS::takeC( C& ),

                       // потому что аргумент имеет тип NS::C, следовательно,

                       // принимается во внимание функция takeC(),

                       // объявленная в пространстве имен NS

         return 0;

      }

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

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

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

      char* format( int );

      void g() {

         char *format( double );

         char* format( char* );

         format(3);   // вызывается format( double )

      }

      Так как format(int), объявленная в глобальной области видимости, скрыта, она не включается в множество функций-кандидатов.

      Кандидаты могут быть введены с помощью using-объявлений, видимых в точке вызова:

      namespace libs_R_us {

         int max( int, int );

         double max( double, double );

      }

      char max( char, char );

      void func()

      {

         // функции из пространства имен невидимы

         // все три вызова разрешаются в пользу глобальной функции max( char, char )

         max( 87, 65 );

         max( 35.5, 76.6 );

         max( 'J', 'L' );

      }

      Функции max(), определенные в пространстве имен libs_R_us, невидимы в точке вызова. Единственной видимой является функция max() из глобальной области; только она входит в множество функций-кандидатов и вызывается при каждом из трех обращений к func(). Мы можем воспользоваться using-объявлением, чтобы сделать видимыми функции max() из пространства имен libs_R_us. Куда поместить using-объявление? Если включить его в глобальную область видимости:

      char max( char, char );

      using libs_R_us::max;   // using-объявление

      то функции max() из libs_R_us добавляются в множество перегруженных функций, которое уже содержит max(), объявленную в глобальной области. Теперь все три функции видны внутри func() и становятся кандидатами. В этой ситуации вызовы func() разрешаются следующим образом:

      void func()

      {

         max( 87, 65 );     // вызывается libs_R_us::max( int, int )

         max( 35.5, 76.6 ); // вызывается libs_R_us::max( double, double )

         max( 'J', 'L' );   // вызывается ::max( char, char )

      }

      Но что будет, если мы введем using-объявление в локальную область видимости функции func(), как показано в данном примере?

      void func()

      {

         // using-объявление

         using libs_R_us::max;

         // те же вызовы функций, что и выше

      }

      Какие из функций max() будут включены в множество кандидатов? Напомним, что using-объявления вкладываются друг в друга. При наличии такого объявления в локальной области глобальная функция max(char, char) оказывается скрытой, так что в точке вызова видны только


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