Читаем Язык программирования C++. Пятое издание полностью

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

Если происходит вызов функции debug_rep() с указателем:

cout << debug_rep(&s) << endl;

то обе функции создают подходящие экземпляры:

• debug_rep(const string*&) — экземпляр первой версии функции debug_rep() с привязкой параметра Т к типу string*;

• debug_rep(string*) — экземпляр второй версии функции debug_rep() с привязкой параметра Т к типу string.

Точным соответствием для этого вызова является экземпляр второй версии функции debug_rep(). Создание экземпляра первой версии требует преобразования простого указателя в указатель на константу. Обычный подбор функции гласит, что следует предпочесть второй шаблон, и в действительности так и происходит.

Несколько подходящих шаблонов

В качестве другого примера рассмотрим следующий вызов:

const string *sp = &s

cout << debug_rep(sp) << endl;

Здесь подходящими являются оба шаблона, и оба обеспечивают точное соответствие:

• debug_rep(const string*&) — экземпляр первой версии шаблона с привязкой параметра Т к типу const string*;

• debug_rep(const string*) — экземпляр второй версии шаблона с привязкой параметра Т к типу const string.

В данном случае обычный подбор функции не может различить эти два вызова. Можно было бы ожидать, что этот вызов будет неоднозначен. Однако благодаря специальному правилу для перегруженных шаблонов функций этот вызов решается как debug_rep(Т*), поскольку это более специализированный шаблон.

Причина для этого правила в том, что без него не было бы никакого способа вызвать версию функции debug_rep() для указателя на константу. Проблема в том, что к шаблону debug_rep(const Т&) подходит практически любой тип, включая типы указателя. Этот шаблон является более общим, чем debug_rep(Т*), который может быть вызван только для типов указателя. Без этого правила вызовы с передачей указателей на константу всегда будут неоднозначны.

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

Не шаблон и перегрузка шаблона

Для следующего примера определим обычную, не шаблонную версию функции debug_rep(), выводящую строки в двойных кавычках:

// вывод строк в двойных кавычках

string debug_rep(const string &s) {

 return '"' + s + '"';

}

Теперь, когда происходит вызов функции debug_rep() для строки:

string s("hi");

cout << debug_rep(s) << endl;

есть две одинаково хорошо подходящих функции:

• debug_rep(const string&) — первый шаблон с привязкой параметра T к типу string;

• debug_rep(const string&) — обычная, не шаблонная функция.

В данном случае у обеих функций одинаковый список параметров, поэтому каждая из них обеспечивает одинаково хорошее соответствие этому вызову. Однако выбирается нешаблонная версия. По тем же причинам, по которым предпочитаются наиболее специализированные из одинаково хорошо подходящих шаблонов функций, нешаблонная функция предпочитается при одинаково хорошем соответствии с шаблонной функцией.

Когда нешаблонная функция обеспечивает одинаково хорошее соответствие с шаблонной функцией, предпочитается нешаблонная версия.

Перегруженные шаблоны и преобразования

До сих пор не рассматривался случай с указателями на символьные строки в стиле С и строковые литералы. Теперь, когда имеется версия функции debug_rep(), получающая строку, можно было бы ожидать, что ей будет соответствовать вызов, которому переданы символьные строки. Однако рассмотрим этот вызов:

cout << debug_rep("hi world!") << endl; // вызов debug_rep(T*)

Здесь подходящими являются все три функции debug_rep():

• debug_rep(const Т&) — с привязкой параметра Т к типу char[10];

• debug_rep(Т*) — с привязкой параметра Т к типу соnst char;

• debug_rep(const string&) — требующая преобразования из const char* в string.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных