- •1. Начинаем
 - •1.1. Решение задачи
 - •1.2. Программа на языке C++
 - •1.2.1. Порядок выполнения инструкций
 - •1.3. Директивы препроцессора
 - •1.4. Немного о комментариях
 - •1.5. Первый взгляд на ввод/вывод
 - •1.5.1. Файловый ввод/вывод
 - •2. Краткий обзор С++
 - •2.1. Встроенный тип данных “массив”
 - •2.2. Динамическое выделение памяти и указатели
 - •2.3. Объектный подход
 - •2.4. Объектно-ориентированный подход
 - •2.5. Использование шаблонов
 - •2.6. Использование исключений
 - •2.7. Использование пространства имен
 - •2.8. Стандартный массив – это вектор
 - •3. Типы данных С++
 - •3.1. Литералы
 - •3.2. Переменные
 - •3.2.1. Что такое переменная
 - •3.2.2. Имя переменной
 - •3.2.3. Определение объекта
 - •3.3. Указатели
 - •3.4. Строковые типы
 - •3.4.1. Встроенный строковый тип
 - •3.4.2. Класс string
 - •3.5. Спецификатор const
 - •3.6. Ссылочный тип
 - •3.7. Тип bool
 - •3.8. Перечисления
 - •3.9. Тип “массив”
 - •3.9.1. Многомерные массивы
 - •3.9.2. Взаимосвязь массивов и указателей
 - •3.10. Класс vector
 - •3.11. Класс complex
 - •3.12. Директива typedef
 - •3.13. Спецификатор volatile
 - •3.14. Класс pair
 - •3.15. Типы классов
 - •4. Выражения
 - •4.1. Что такое выражение?
 - •4.2. Арифметические операции
 - •4.3. Операции сравнения и логические операции
 - •4.4. Операции присваивания
 - •4.5. Операции инкремента и декремента
 - •4.6. Операции с комплексными числами
 - •4.7. Условное выражение
 - •4.8. Оператор sizeof
 - •4.9. Операторы new и delete
 - •4.10. Оператор “запятая”
 - •4.11. Побитовые операторы
 - •4.12. Класс bitset
 - •4.13. Приоритеты
 - •4.14. Преобразования типов
 - •4.14.1. Неявное преобразование типов
 - •4.14.2. Арифметические преобразования типов
 - •4.14.3. Явное преобразование типов
 - •4.14.4. Устаревшая форма явного преобразования
 - •4.15. Пример: реализация класса Stack
 - •5. Инструкции
 - •5.1. Простые и составные инструкции
 - •5.2. Инструкции объявления
 - •5.3. Инструкция if
 - •5.4. Инструкция switch
 - •5.5. Инструкция цикла for
 - •5.6. Инструкция while
 - •5.8. Инструкция do while
 - •5.8. Инструкция break
 - •5.9. Инструкция continue
 - •5.10. Инструкция goto
 - •5.11. Пример связанного списка
 - •5.11.1. Обобщенный список
 - •6. Абстрактные контейнерные типы
 - •6.1. Система текстового поиска
 - •6.2. Вектор или список?
 - •6.3. Как растет вектор?
 - •6.4. Как определить последовательный контейнер?
 - •6.5. Итераторы
 - •6.6. Операции с последовательными контейнерами
 - •6.6.1. Удаление
 - •6.6.2. Присваивание и обмен
 - •6.6.3. Обобщенные алгоритмы
 - •6.7. Читаем текстовый файл
 - •6.8. Выделяем слова в строке
 - •6.9. Обрабатываем знаки препинания
 - •6.10. Приводим слова к стандартной форме
 - •6.11. Дополнительные операции со строками
 - •6.12. Строим отображение позиций слов
 - •6.12.1. Определение объекта map и заполнение его элементами
 - •6.12.2. Поиск и извлечение элемента отображения
 - •6.12.3. Навигация по элементам отображения
 - •6.12.4. Словарь
 - •6.12.5. Удаление элементов map
 - •6.13. Построение набора стоп-слов
 - •6.13.1. Определение объекта set и заполнение его элементами
 - •6.13.2. Поиск элемента
 - •6.13.3. Навигация по множеству
 - •6.14. Окончательная программа
 - •6.15. Контейнеры multimap и multiset
 - •6.16. Стек
 - •6.17. Очередь и очередь с приоритетами
 - •6.18. Вернемся в классу iStack
 - •7. Функции
 - •7.1. Введение
 - •7.2. Прототип функции
 - •7.2.1. Тип возвращаемого функцией значения
 - •7.2.2. Список параметров функции
 - •7.2.3. Проверка типов формальных параметров
 - •7.3. Передача аргументов
 - •7.3.1. Параметры-ссылки
 - •7.3.2. Параметры-ссылки и параметры-указатели
 - •7.3.3. Параметры-массивы
 - •7.3.4. Абстрактные контейнерные типы в качестве параметров
 - •7.3.5. Значения параметров по умолчанию
 - •7.3.6. Многоточие
 - •7.4. Возврат значения
 - •7.4.1. Передача данных через параметры и через глобальные объекты
 - •7.5. Рекурсия
 - •7.6. Встроенные функции
 - •7.7. Директива связывания extern "C" A
 - •7.8. Функция main(): разбор параметров командной строки
 - •7.8.1. Класс для обработки параметров командной строки
 - •7.9. Указатели на функции
 - •7.9.1. Тип указателя на функцию
 - •7.9.2. Инициализация и присваивание
 - •7.9.3. Вызов
 - •7.9.4. Массивы указателей на функции
 - •7.9.5. Параметры и тип возврата
 - •7.9.6. Указатели на функции, объявленные как extern "C"
 - •8. Область видимости и время жизни
 - •8.1. Область видимости
 - •8.1.1. Локальная область видимости
 - •8.2. Глобальные объекты и функции
 - •8.2.1. Объявления и определения
 - •8.2.2. Сопоставление объявлений в разных файлах
 - •8.2.3. Несколько слов о заголовочных файлах
 - •8.3. Локальные объекты
 - •8.3.1. Автоматические объекты
 - •8.3.2. Регистровые автоматические объекты
 - •8.3.3. Статические локальные объекты
 - •8.4. Динамически размещаемые объекты
 - •8.4.1. Динамическое создание и уничтожение единичных объектов
 - •8.4.2. Шаблон auto_ptr А
 - •8.4.3. Динамическое создание и уничтожение массивов
 - •8.4.4. Динамическое создание и уничтожение константных объектов
 - •8.4.5. Оператор размещения new А
 - •8.5. Определения пространства имен А
 - •8.5.1. Определения пространства имен
 - •8.5.2. Оператор разрешения области видимости
 - •8.5.3. Вложенные пространства имен
 - •8.5.4. Определение члена пространства имен
 - •8.5.5. ПОО и члены пространства имен
 - •8.5.6. Безымянные пространства имен
 - •8.6. Использование членов пространства имен А
 - •8.6.1. Псевдонимы пространства имен
 - •8.6.2. Using-объявления
 - •8.6.3. Using-директивы
 - •8.6.4. Стандартное пространство имен std
 - •9. Перегруженные функции
 - •9.1. Объявления перегруженных функций
 - •9.1.1. Зачем нужно перегружать имя функции
 - •9.1.2. Как перегрузить имя функции
 - •9.1.3. Когда не надо перегружать имя функции
 - •9.1.4. Перегрузка и область видимости A
 - •9.1.5. Директива extern "C" и перегруженные функции A
 - •9.1.6. Указатели на перегруженные функции A
 - •9.1.7. Безопасное связывание A
 - •9.2. Три шага разрешения перегрузки
 - •9.3. Преобразования типов аргументов A
 - •9.3.1. Подробнее о точном соответствии
 - •9.3.2. Подробнее о расширении типов
 - •9.3.3. Подробнее о стандартном преобразовании
 - •9.3.4. Ссылки
 - •9.4. Детали разрешения перегрузки функций
 - •9.4.1. Функции-кандидаты
 - •9.4.2. Устоявшие функции
 - •9.4.3. Наилучшая из устоявших функция
 - •9.4.4. Аргументы со значениями по умолчанию
 - •10. Шаблоны функций
 - •10.1. Определение шаблона функции
 - •10.2. Конкретизация шаблона функции
 - •10.3. Вывод аргументов шаблона А
 - •10.4. Явное задание аргументов шаблона A
 - •10.5. Модели компиляции шаблонов А
 - •10.5.1. Модель компиляции с включением
 - •10.5.2. Модель компиляции с разделением
 - •10.5.3. Явные объявления конкретизации
 - •10.6. Явная специализация шаблона А
 - •10.7. Перегрузка шаблонов функций А
 - •10.8. Разрешение перегрузки при конкретизации A
 - •10.9. Разрешение имен в определениях шаблонов А
 - •10.10. Пространства имен и шаблоны функций А
 - •10.11. Пример шаблона функции
 - •11. Обработка исключений
 - •11.1. Возбуждение исключения
 - •11.2. try-блок
 - •11.3. Перехват исключений
 - •11.3.1. Объекты-исключения
 - •11.3.2. Раскрутка стека
 - •11.3.3. Повторное возбуждение исключения
 - •11.3.4. Перехват всех исключений
 - •11.4. Спецификации исключений
 - •11.4.1. Спецификации исключений и указатели на функции
 - •11.5. Исключения и вопросы проектирования
 - •12. Обобщенные алгоритмы
 - •12.1. Краткий обзор
 - •12.2. Использование обобщенных алгоритмов
 - •12.3. Объекты-функции
 - •12.3.1. Предопределенные объекты-функции
 - •12.3.3. Сравнительные объекты-функции
 - •12.3.4. Логические объекты-функции
 - •12.3.5. Адаптеры функций для объектов-функций
 - •12.3.6. Реализация объекта-функции
 - •12.4. Еще раз об итераторах
 - •12.4.1. Итераторы вставки
 - •12.4.2. Обратные итераторы
 - •12.4.3. Потоковые итераторы
 - •12.4.4. Итератор istream_iterator
 - •12.4.5. Итератор ostream_iterator
 - •12.4.6. Пять категорий итераторов
 - •12.5. Обобщенные алгоритмы
 - •12.5.1. Алгоритмы поиска
 - •12.5.2. Алгоритмы сортировки и упорядочения
 - •12.5.3. Алгоритмы удаления и подстановки
 - •12.5.4. Алгоритмы перестановки
 - •12.5.5. Численные алгоритмы
 - •12.5.6. Алгоритмы генерирования и модификации
 - •12.5.7. Алгоритмы сравнения
 - •12.5.8. Алгоритмы работы с множествами
 - •12.5.9. Алгоритмы работы с хипом
 - •12.6.1. Операция list_merge()
 - •12.6.2. Операция list::remove()
 - •12.6.3. Операция list::remove_if()
 - •12.6.4. Операция list::reverse()
 - •12.6.5. Операция list::sort()
 - •12.6.6. Операция list::splice()
 - •12.6.7. Операция list::unique()
 - •13. Классы
 - •13.1. Определение класса
 - •13.1.1. Данные-члены
 - •13.1.2. Функции-члены
 - •13.1.3. Доступ к членам
 - •13.1.4. Друзья
 - •13.1.5. Объявление и определение класса
 - •13.2. Объекты классов
 - •13.3. Функции-члены класса
 - •13.3.1. Когда использовать встроенные функции-члены
 - •13.3.2. Доступ к членам класса
 - •13.3.3. Закрытые и открытые функции-члены
 - •13.3.4. Специальные функции-члены
 - •13.3.5. Функции-члены со спецификаторами const и volatile
 - •13.3.6. Объявление mutable
 - •13.4. Неявный указатель this
 - •13.4.1. Когда использовать указатель this
 - •13.5. Статические члены класса
 - •13.5.1. Статические функции-члены
 - •13.6. Указатель на член класса
 - •13.6.1. Тип члена класса
 - •13.6.2. Работа с указателями на члены класса
 - •13.6.3. Указатели на статические члены класса
 - •13.7. Объединение – класс, экономящий память
 - •13.8. Битовое поле – член, экономящий память
 - •13.9. Область видимости класса A
 - •13.9.1. Разрешение имен в области видимости класса
 - •13.10. Вложенные классы A
 - •13.10.1. Разрешение имен в области видимости вложенного класса
 - •13.11. Классы как члены пространства имен A
 - •13.12. Локальные классы A
 - •14. Инициализация, присваивание и уничтожение класса
 - •14.1. Инициализация класса
 - •14.2. Конструктор класса
 - •14.2.1. Конструктор по умолчанию
 - •14.2.2. Ограничение прав на создание объекта
 - •14.2.3. Копирующий конструктор
 - •14.3. Деструктор класса
 - •14.3.1. Явный вызов деструктора
 - •14.3.2. Опасность увеличения размера программы
 - •14.4. Массивы и векторы объектов
 - •14.4.1. Инициализация массива, распределенного из хипа A
 - •14.4.2. Вектор объектов
 - •14.5. Список инициализации членов
 - •14.6. Почленная инициализация A
 - •14.6.1. Инициализация члена, являющегося объектом класса
 - •14.7. Почленное присваивание A
 - •14.8. Соображения эффективности A
 - •15. Перегруженные операторы и определенные пользователем преобразования
 - •15.1. Перегрузка операторов
 - •15.1.1. Члены и не члены класса
 - •15.1.2. Имена перегруженных операторов
 - •15.1.3. Разработка перегруженных операторов
 - •15.2. Друзья
 - •15.3. Оператор =
 - •15.4. Оператор взятия индекса
 - •15.5. Оператор вызова функции
 - •15.6. Оператор “стрелка”
 - •15.7. Операторы инкремента и декремента
 - •15.8. Операторы new и delete
 - •15.8.1. Операторы new[ ] и delete [ ]
 - •15.8.2. Оператор размещения new() и оператор delete()
 - •15.9. Определенные пользователем преобразования
 - •15.9.1. Конвертеры
 - •15.9.2. Конструктор как конвертер
 - •15.10. Выбор преобразования A
 - •15.10.1. Еще раз о разрешении перегрузки функций
 - •15.10.2. Функции-кандидаты
 - •15.10.3. Функции-кандидаты для вызова функции в области видимости класса
 - •15.10.4. Ранжирование последовательностей определенных пользователем преобразований
 - •15.11. Разрешение перегрузки и функции-члены A
 - •15.11.1. Объявления перегруженных функций-членов
 - •15.11.2. Функции-кандидаты
 - •15.11.3. Устоявшие функции
 - •15.12. Разрешение перегрузки и операторы A
 - •15.12.1. Операторные функции-кандидаты
 - •15.12.2. Устоявшие функции
 - •15.12.3. Неоднозначность
 - •16. Шаблоны классов
 - •16.1. Определение шаблона класса
 - •16.1.1. Определения шаблонов классов Queue и QueueItem
 - •16.2. Конкретизация шаблона класса
 - •16.2.1. Аргументы шаблона для параметров-констант
 - •16.3. Функции-члены шаблонов классов
 - •16.3.1. Функции-члены шаблонов Queue и QueueItem
 - •16.4. Объявления друзей в шаблонах классов
 - •16.4.1. Объявления друзей в шаблонах Queue и QueueItem
 - •16.5. Статические члены шаблонов класса
 - •16.6. Вложенные типы шаблонов классов
 - •16.7. Шаблоны-члены
 - •16.8. Шаблоны классов и модель компиляции A
 - •16.8.1. Модель компиляции с включением
 - •16.8.2. Модель компиляции с разделением
 - •16.8.3. Явные объявления конкретизации
 - •16.9. Специализации шаблонов классов A
 - •16.10. Частичные специализации шаблонов классов A
 - •16.11. Разрешение имен в шаблонах классов A
 - •16.12. Пространства имен и шаблоны классов
 - •16.13. Шаблон класса Array
 - •17. Наследование и подтипизация классов
 - •17.1. Определение иерархии классов
 - •17.1.1. Объектно-ориентированное проектирование
 - •17.2. Идентификация членов иерархии
 - •17.2.1. Определение базового класса
 - •17.2.2. Определение производных классов
 - •17.2.3. Резюме
 - •17.3. Доступ к членам базового класса
 - •17.4. Конструирование базового и производного классов
 - •17.4.1. Конструктор базового класса
 - •17.4.2. Конструктор производного класса
 - •17.4.3. Альтернативная иерархия классов
 - •17.4.4. Отложенное обнаружение ошибок
 - •17.4.5. Деструкторы
 - •17.5. Виртуальные функции в базовом и производном классах
 - •17.5.1. Виртуальный ввод/вывод
 - •17.5.2. Чисто виртуальные функции
 - •17.5.3. Статический вызов виртуальной функции
 - •17.5.4. Виртуальные функции и аргументы по умолчанию
 - •17.5.5. Виртуальные деструкторы
 - •17.5.6. Виртуальная функция eval()
 - •17.5.7. Почти виртуальный оператор new
 - •17.5.8. Виртуальные функции, конструкторы и деструкторы
 - •17.6. Почленная инициализация и присваивание A
 - •17.7. Управляющий класс UserQuery
 - •17.7.1. Определение класса UserQuery
 - •17.8. Соберем все вместе
 - •18. Множественное и виртуальное наследование
 - •18.1. Готовим сцену
 - •18.2. Множественное наследование
 - •18.3. Открытое, закрытое и защищенное наследование
 - •18.3.1. Наследование и композиция
 - •18.3.2. Открытие отдельных членов
 - •18.3.3. Защищенное наследование
 - •18.3.4. Композиция объектов
 - •18.4. Область видимости класса и наследование
 - •18.4.1. Область видимости класса при множественном наследовании
 - •18.5. Виртуальное наследование A
 - •18.5.1. Объявление виртуального базового класса
 - •18.5.2. Специальная семантика инициализации
 - •18.5.3. Порядок вызова конструкторов и деструкторов
 - •18.5.4. Видимость членов виртуального базового класса
 - •18.6. Пример множественного виртуального наследования A
 - •18.6.1. Порождение класса, контролирующего выход за границы массива
 - •18.6.2. Порождение класса отсортированного массива
 - •18.6.3. Класс массива с множественным наследованием
 - •19. Применение наследования в C++
 - •19.1. Идентификация типов во время выполнения
 - •19.1.1. Оператор dynamic_cast
 - •19.1.2. Оператор typeid
 - •19.1.3. Класс type_info
 - •19.2. Исключения и наследование
 - •19.2.1. Исключения, определенные как иерархии классов
 - •19.2.2. Возбуждение исключения типа класса
 - •19.2.3. Обработка исключения типа класса
 - •19.2.4. Объекты-исключения и виртуальные функции
 - •19.2.5. Раскрутка стека и вызов деструкторов
 - •19.2.6. Спецификации исключений
 - •19.2.7. Конструкторы и функциональные try-блоки
 - •19.2.8. Иерархия классов исключений в стандартной библиотеке C++
 - •19.3. Разрешение перегрузки и наследование A
 - •19.3.1. Функции-кандидаты
 - •19.3.2. Устоявшие функции и последовательности пользовательских преобразований
 - •19.3.3. Наилучшая из устоявших функций
 - •20. Библиотека iostream
 - •20.1. Оператор вывода <<
 - •20.2. Ввод
 - •20.2.1. Строковый ввод
 - •20.3. Дополнительные операторы ввода/вывода
 - •20.4. Перегрузка оператора вывода
 - •20.5. Перегрузка оператора ввода
 - •20.6. Файловый ввод/вывод
 - •20.7. Состояния потока
 - •20.8. Строковые потоки
 - •20.9. Состояние формата
 - •20.10. Сильно типизированная библиотека
 - •21. Обобщенные алгоритмы в алфавитном порядке
 - •Алгоритм accumulate()
 - •Алгоритм adjacent_difference()
 - •Алгоритм adjacent_find()
 - •Алгоритм binary_search()
 - •Алгоритм copy()
 - •Алгоритм copy_backward()
 - •Алгоритм count()
 - •Алгоритм count_if()
 - •Алгоритм equal()
 - •Алгоритм equal_range()
 - •Алгоритм fill()
 - •Алгоритм fill_n()
 - •Алгоритм find()
 - •Алгоритм find_if()
 - •Алгоритм find_end()
 - •Алгоритм find_first_of()
 - •Алгоритм for_each()
 - •Алгоритм generate()
 - •Алгоритм generate_n()
 - •Алгоритм includes()
 - •Алгоритм inner_product()
 - •Алгоритм inplace_merge()
 - •Алгоритм iter_swap()
 - •Алгоритм lexicographical_compare()
 - •Алгоритм lower_bound()
 - •Алгоритм max()
 - •Алгоритм max_element()
 - •Алгоритм min()
 - •Алгоритм min_element()
 - •Алгоритм merge()
 - •Алгоритм mismatch()
 - •Алгоритм next_permutation()
 - •Алгоритм nth_element()
 - •Алгоритм partial_sort()
 - •Алгоритм partial_sort_copy()
 - •Алгоритм partial_sum()
 - •Алгоритм partition()
 - •Алгоритм prev_permutation()
 - •Алгоритм random_shuffle()
 - •Алгоритм remove()
 - •Алгоритм remove_copy()
 - •Алгоритм remove_if()
 - •Алгоритм remove_copy_if()
 - •Алгоритм replace()
 - •Алгоритм replace_copy()
 - •Алгоритм replace_if()
 - •Алгоритм replace_copy_if()
 - •Алгоритм reverse()
 - •Алгоритм reverse_copy()
 - •Алгоритм rotate()
 - •Алгоритм rotate_copy()
 - •Алгоритм search()
 - •Алгоритм search_n()
 - •Алгоритм set_difference()
 - •Алгоритм set_intersection()
 - •Алгоритм set_symmetric_difference()
 - •Алгоритм set_union()
 - •Алгоритм sort()
 - •Алгоритм stable_partition()
 - •Алгоритм stable_sort()
 - •Алгоритм swap()
 - •Алгоритм swap_ranges()
 - •Алгоритм transform()
 - •Алгоритм unique()
 - •Алгоритм unique_copy()
 - •Алгоритм upper_bound()
 - •Алгоритмы для работы с хипом
 - •Алгоритм make_heap()
 - •Алгоритм pop_heap()
 - •Алгоритм push_heap()
 - •Алгоритм sort_heap()
 
(a)void print( int *, int ); int arr[6];
print( arr, 6 ); // вызов функции
(b)void manip( int, int );
manip( 'a', 'z' ); // вызов функции
(c)int calc( int, int );
double dobj;
double = calc( 55.4, dobj ) // вызов функции
(d)void set( const int * ); int *pi;
set( pi ); // вызов функции
Упражнение 9.8 Какие из данных вызовов ошибочны из-за того, что не существует преобразования между
(a)enum Stat { Fail, Pass }; void test( Stat );
text( 0 ); // вызов функции
(b)void reset( void *);
reset( 0 ); // вызов функции
(c)void set( void * ); int *pi;
set( pi ); // вызов функции
(d)#include <list> list<int> oper();
void print( oper() ); // вызов функции
(e)void print( const int ); int iobj;
типом фактического аргумента и формального параметра: print( iobj ); // вызов функции
9.4. Детали разрешения перегрузки функций
В разделе 9.2 мы уже упоминали, что процесс разрешения перегрузки функций состоит из трех шагов:
1.Установить множество функций-кандидатов для разрешения данного вызова, а также свойства списка фактических аргументов.
2.Отобрать из множества кандидатов устоявшие функции – те, которые могут быть вызваны с данным списком фактических аргументов при учете их числа и типов.
3.Выбрать функцию, лучше всего соответствующую вызову, подвергнув ранжированию преобразования, которые необходимо применить к фактическим аргументам, чтобы привести их в соответствие с формальными параметрами устоявшей функции.
Теперь мы готовы к тому, чтобы изучить эти шаги более детально.
9.4.1. Функции-кандидаты
Функцией-кандидатом называется функция, имеющая то же имя, что и вызванная. Кандидаты отыскиваются двумя способами:
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;
вызванная функция, добавляются в множество кандидатов:
}
Таким образом, совокупность кандидатов является объединением множества функций, видимых в точке вызова, и множества функций, объявленных в том же пространстве имен, к которому принадлежат типы фактических аргументов.
При идентификации множества перегруженных функций, видимых в точке вызова, применимы уже рассмотренные ранее правила.
Функция, объявленная во вложенной области видимости, скрывает, а не перегружает одноименную функцию во внешней области. В такой ситуации кандидатами будут только функции из во вложенной области, т.е. такие, которые не скрыты при вызове. В
следующем примере функциями-кандидатами, видимыми в точке вызова, являются
char* format( int ); void g() {
char *format( double ); char* format( char* );
format(3); // вызывается format( double )
format(double) и format(char*):
}
Так как format(int), объявленная в глобальной области видимости, скрыта, она не включается в множество функций-кандидатов.
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' );
Кандидаты могут быть введены с помощью using-объявлений, видимых в точке вызова:
}
Функции 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()  | 
	
  | 
{  | 
	// вызывается libs_R_us::max( int, int )  | 
max( 87, 65 );  | 
|
max( 35.5, 76.6 ); // вызывается libs_R_us::max( double,  | 
|
double )  | 
	// вызывается ::max( char, char )  | 
max( 'J', 'L' );  | 
|
}
Но что будет, если мы введем using-объявление в локальную область видимости функции
void func()
{
//using-объявление using libs_R_us::max;
//те же вызовы функций, что и выше
func(), как показано в данном примере?
}
Какие из функций max() будут включены в множество кандидатов? Напомним, что using-объявления вкладываются друг в друга. При наличии такого объявления в локальной области глобальная функция max(char, char) оказывается скрытой, так что
libs_R_us::max( int, int );
в точке вызова видны только libs_R_us::max( double, double );
void func()
{
//using-объявление
//глобальная функция max( char, char ) скрыта using libs_R_us::max;
max( 87, 65 );  | 
	// вызывается libs_R_us::max( int, int )  | 
max( 35.5, 76.6 ); // вызывается libs_R_us::max( double,  | 
|
double )  | 
	// вызывается libs_R_us::max( int, int )  | 
max( 'J', 'L' );  | 
|
Они и являются кандидатами. Теперь вызовы func() разрешаются следующим образом:
}
Using-директивы также оказывают влияние на состав множества функций-кандидатов. Предположим, мы решили их использовать, чтобы сделать функции max() из пространства имен libs_R_us видимыми в func(). Если разместить следующую usingдирективу в глобальной области видимости, то множество функций-кандидатов будет состоять из глобальной функции max(char, char) и функций max(int, int) и max(double, double), объявленных в libs_R_us:
namespace libs_R_us { int max( int, int );
double max( double, double );
}
char max( char, char );
using namespace libs_R_us; // using-директива
void func()  | 
	
  | 
{  | 
	// вызывается libs_R_us::max( int, int )  | 
max( 87, 65 );  | 
|
max( 35.5, 76.6 ); // вызывается libs_R_us::max( double,  | 
|
double )  | 
	// вызывается ::max( int, int )  | 
max( 'J', 'L' );  | 
|
}
Что будет, если поместить using-директиву в локальную область видимости, как в
void func()
{
// using-директива
using namespace libs_R_us;
// те же вызовы функций, что и выше
следующем примере?
}
Какие из функций max() окажутся среди кандидатов? Напомним, что using-директива делает члены пространства имен видимыми, словно они были объявлены вне этого пространства, в той точке, где такая директива помещается. В нашем примере члены libs_R_us видимы в локальной области функции func(), как будто они объявлены вне пространства – в глобальной области. Отсюда следует, что множество перегруженных
max( char, char ); libs_R_us::max( int,
int );
функций, видимых внутри func(), то же, что и раньше, т.е. включает в себя libs_R_us::max( double, double );
В локальной или глобальной области видимости появляется using-директива, на
void func()
{
using namespace libs_R_us;
max( 87, 65 );  | 
	//  | 
	вызывается  | 
	libs_R_us::max(  | 
	int, int )  | 
max( 35.5, 76.6 ); // вызывается libs_R_us::max( double,  | 
||||
double )  | 
	// вызывается ::max( int, int )  | 
|||
max( 'J', 'L' );  | 
||||
разрешение вызовов функции func() не влияет:
}
