- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
Когда происходит вызов функции print(), компилятор ищет сначала объявление этого имени. Он находит локальное объявление функции print(), получающей один параметр типа int. Как только имя найдено, компилятор игнорирует такое же имя в любой внешней области видимости. Он полагает данное объявление единственно доступным для использования. Остается лишь удостовериться в допустимости использования этого имени.
В языке С++ поиск имени осуществляется до проверки соответствия типов.
Первый вызов передает функции print() строковый литерал, но единственное ее объявление, находящееся в области видимости, имеет параметр типа int. Строковый литерал не может быть преобразован в тип int, поэтому вызов ошибочен. Функция print(const string&), которая соответствовала бы этому вызову, скрыта и не рассматривается.
Когда происходит вызов функции print() с передачей аргумента типа double(), процесс повторяется. Компилятор находит локальное определение функции print(int). Но аргумент типа double может быть преобразован в значение типа int, поэтому вызов корректен.
Если бы объявление print(int) находилось в той же области видимости, что и объявления других версий функции print(), это была бы еще одна ее перегруженная версия. В этом случае вызовы распознавались бы по-другому, поскольку компилятор видел бы все три функции:
void print(const string &);
void print(double); // перегружает функцию print
void print(int); // еще один экземпляр перегрузки
void fooBar2(int ival) {
print("Value: "); // вызов print(const string &)
print(ival); // вызов print(int)
print(3.14); // вызов print(double)
}
6.5. Специальные средства
В этом разделе рассматриваются три связанных с функциями средства, которые полезны во многих, но не во всех программах: аргументы по умолчанию, встраиваемые функции и функции constexpr, а также некоторые другие средства, обычно используемые во время отладки.
6.5.1. Аргументы по умолчанию
Параметры некоторых функций могут обладать конкретными значениями, используемыми в большинстве, но не во всех вызовах. Такие обычно используемые значения называют аргументом по умолчанию (default argument). Функции с аргументами по умолчанию могут быть вызваны с ними или без них.
Например, для представления содержимого окна можно было бы использовать тип string. Мы могли бы хотеть, чтобы по умолчанию у окна была определенная высота, ширина и фоновый символ. Но мы могли бы также захотеть позволить пользователям использовать собственные значения, кроме значений по умолчанию. Чтобы приспособить и значение по умолчанию, и определяемое пользователем, мы объявили бы функцию, представляющую окно, следующим образом:
typedef string::size_type sz; // typedef см. p. 2.5.1
string screen(sz ht = 24, sz wid = 80, char backgrnd = ' ');
Здесь мы предоставили для каждого параметра значение по умолчанию. Аргумент по умолчанию определяется как инициализатор параметра в списке параметров. Значения по умолчанию можно определить как для одного, так и для нескольких параметров. Но если у параметра есть аргумент по умолчанию, то все параметры, следующие за ним, также должны иметь аргументы по умолчанию.
Вызов функции с аргументами по умолчаниюЕсли необходимо использовать аргумент по умолчанию, его значение при вызове функции пропускают. Поскольку функция screen() предоставляет значения по умолчанию для всех параметров, мы можем вызвать ее без аргументов, с одним, двумя или тремя аргументами:
string window;
window = screen(); // эквивалент screen(24, 80, ' ')
window = screen(66); // эквивалент screen(66, 80, ' ')
window = screen(66, 256); // screen(66, 256, ' ')
window = screen(66, 256, '#'); // screen(66, 256, '#')
Аргументы в вызове распознаются по позиции. Значения по умолчанию используются для аргументов, крайних справа. Например, чтобы переопределить значение по умолчанию параметра background, следует поставить также аргументы для параметров height и width:
window = screen(, , '?'); // ошибка: можно пропустить аргументы только
// крайние справа
window = screen('?'); // вызов screen('?', 80, ' ')
Обратите внимание, что второй вызов, передающий одно символьное значение, вполне допустим. Несмотря на допустимость, это вряд ли то, что ожидалось. Вызов допустим потому, что символ '?' имеет тип char, а он может быть преобразован в тип крайнего левого параметра. Это параметр типа string::size_type, который является целочисленным беззнаковым типом. В этом вызове аргумент типа char неявно преобразуется в тип string::size_type и передается как аргумент параметру height. На машине авторов символ '?' имеет шестнадцатеричное значение 0x3F, соответствующее десятичному 63. Таким образом, этот вызов присваивает параметру height значение 63.
Одной из задач при разработке функции с аргументами по умолчанию является упорядочивание параметров так, чтобы те из них, для которых использование значения по умолчанию вероятней всего, располагались последними.
Объявление аргумента по умолчаниюХотя вполне обычной практикой является объявление функции однажды в заголовке, вполне допустимо многократно объявлять ее повторно. Однако у каждого параметра может быть свое значение по умолчанию, определенное только однажды в данной области видимости. Таким образом, любое последующее объявление может добавить значение по умолчанию только для того параметра, у которого ранее не было определено значение по умолчанию. Как обычно, значения по умолчанию могут быть определены, только если у всех параметров справа уже есть значения по умолчанию. Рассмотрим следующий пример:
// у параметров height и width нет значений по умолчанию
string screen(sz, sz, char = ' ');
Нельзя изменить уже заявленное значение по умолчанию:
string screen(sz, sz, char = '*'); // ошибка: переобъявление
Но можно добавить аргумент по умолчанию следующим образом:
string screen(sz = 24, sz = 80, char); // ok: добавление аргументов
// по умолчанию
Обычно аргументы по умолчанию определяют при объявлении функции в соответствующем заголовке.
Инициализация аргумента по умолчаниюЛокальные переменные не могут использоваться как аргумент по умолчанию. За исключением этого ограничения, аргумент по умолчанию может быть любым выражением, тип которого приводим к типу параметра:
// объявления wd, def и ht должны располагаться вне функции
sz wd = 80;
char def = ' ';
sz ht();
string screen(sz = ht(), sz = wd, char = def);
string window = screen(); // вызов screen(ht(), 80, ' ')
Поиск имен, используемых для аргументов по умолчанию, осуществляется в пределах объявления функции. Значения, представляемые этими именами, вычисляются во время вызова:
void f2() {
def = '*'; // изменение значения аргумента по умолчанию
sz wd = 100; // скрывает внешнее определение wd, но не изменяет
// значение по умолчанию
window = screen(); // вызов screen(ht(), 80, '*')
}
В функции f2() было изменено значение def. Вызов функции screen передает это измененное значение. Эта функция также объявляет локальную переменную, которая скрывает внешнюю переменную wd. Однако локальное имя wd никак не связано с аргументом по умолчанию, переданным функции screen().
Упражнения раздела 6.5.1Упражнение 6.40. Какое из следующих объявлений (если оно есть) содержит ошибку? Почему?
(a) int ff(int a, int b = 0, int с = 0);
(b) char *init(int ht = 24, int wd, char bckgrnd);
Упражнение 6.41. Какие из следующих вызовов (если они есть) недопустимы? Почему? Какие из них допустимы (если они есть), но, вероятно, не соответствуют намерениям разработчика? Почему?
char *init(int ht, int wd = 80, char bckgrnd = ' ');
(a) init(); (b) init(24,10); (c) init(14, '*');
Упражнение 6.42. Присвойте второму параметру функции make_plural() (см. раздел 6.3.2) аргумент по умолчанию 's'. Проверьте программу, выведя слова "success" и "failure" в единственном и множественном числе.
6.5.2. Встраиваемые функции и функции constexpr

