Точно так же, как и обычные функции, функциональные шаблоны могут быть перегружены. То есть вы можете предусмотреть несколько шаблонов функции с одним и тем же именем, если только они имеют различные заголовки (различное число или различные типы параметров). Вы даже можете объявить комбинацию шаблонов и обычных функций с одинаковым именем. Когда вызывается перегруженная функция, требуется механизм разрешения перегрузки для нахождения требуемой функции или шаблона функции. Например:
template <class T> T sqrt(T);
template <class T> complex<T> sqrt(complex<T>);
double sqrt(double);
void f(complex<double> z)
{
sqrt(2); // sqrt<int> (int)
sqrt(2.0); // sqrt(double)
sqrt(z); // sqrt <double> (complex<double>)
}
Аналогично тому, как шаблон функции является обобщением понятия функции, правила разрешения при наличии шаблонов функций являются обобщением правил разрешения перегрузки функций. Для каждого шаблона осуществляется поиск специализации, наилучшим образом соответствующий списку аргументов. Затем применяются обычные правила разрешения перегрузки применительно к этим специализациям и обычным функциям.
• Вопервых, ищется набор специализаций шаблонов функций, которые примут участие в разрешении перегрузки. Это осуществляется с учетом всех шаблонов функции. Принимается решение, какие аргументы функции были бы использованы (если вообще были бы), если бы в текущей области видимости не было других шаблонов функций и обычных функций с тем же именем. В примере с вызовом sqrt(z) к рассмотрению будут приняты sqrt<double> (complex <double>) и sqrt<complex <double> > (complex <double>).
• Во-вторых, если могут быть вызваны два шаблона функции, и один из них более специализирован, чем другой, на следующих этапах только он и рассматривается. В примере с вызовом sqrt(z), это означает, что предпочтение отдается sqrt<double> (complex <double>) по отношению к sqrt<complex <double> > (complex
<double>): любой вызов, который соответствует sqrt<T> (complex T), так же
соответствует и sqrt<T> (T).
• В-третьих, разрешается перегрузка для этого набора функций, а также для любых обычных функций (для них перегрузка разрешается как для обычных функций). Если аргументы функции шаблона были определены путем выведения по фактическим аргументам шаблона, к ним нельзя применять «продвижение», стандартные и определяемые пользователем преобразования. Для sqrt(2) sqrt<int> (int) является точным соответствием и поэтому ей отдается предпочтение по отношению к sqrt(double).
• В-четвертых, если и обычная функция и специализация подходят одинаково хорошо, отдается предпочтение обычной функции. Следовательно, для sqrt(2.0) выбирается sqrt(double), а не sqrt<double> (double).
• В-пятых, если ни одного соответствия не найдено, вызов считается ошибочным. Если процесс заканчивается с двумя или более одинаково хорошо подходящими вариантами, вызов является неоднозначным и это тоже ошибка.
Опубликовал Kest
September 07 2010 20:20:38 ·
0 Комментариев ·
10751 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.