Комментарии 14
New Year's software resolutions {
I will learn to touch type
I will swear off complex pointers
I will stop betting that "I can do that in one line of C"
I will restrict version numbers to 5 decimal digits
I will go to "Beta" with something that actually works
I will think first before committing a "quick fix"
I will remember that small is beautiful and restrict my functions to 1 or 2 screens
I will stop turning everything into an object
/**/I will really learn C++
I will design first, then code
}
Спасибо, очень лаконично и подробно, как учебник прямо.
Т.е. почему вот тут
выбирается шаблон 2, а не полная специализация для шаблона 1 с const char *, вам очевидно, а почему вложенная область видимости скрывает внешнюю — нет?
Foo("meow"); // #4 — конкретизация шаблона 2 для char
выбирается шаблон 2, а не полная специализация для шаблона 1 с const char *, вам очевидно, а почему вложенная область видимости скрывает внешнюю — нет?
Алгоритм здесь такой. Сначала ищутся точно подходящие нешаблонные функции и конкретизации шаблонов, полные специализации шаблонов на этом этапе вообще не рассматриваются. В нашем случае есть две точно подходящих конкретизации: шаблон 1 для const char* и шаблон 2 для char. Выбирается шаблон 2 как более специализированный. Далее проверяется, нет ли у этого шаблона полной специализации для выведенного аргумента — char. В нашем случае нет, поэтому этот шаблон и выбирается окончательно.
Вообще, такое поведение внутри наслдников только на первый взгляд кажется нелогичным.
Во-первых, поиск и разрешение — последовательные операции. Если поиск был успешным, а разрешение — нет, то чтобы вытащить перегрузку из базового класса компилятору придется повторить итерацию — снова сделать поиск и снова сделать разрешение.
Во-вторых, на мой взгляд, если разработчик сделал внутри наследника перегрузку с подходящей декларацией, но зачем-то затолкал ее в приватную секцию, то это больше похоже на ошибку, чем на злонамерение усложнить поддержку кода. Тут сообщивший об ошибке компилятор будет совершенно прав.
Во-первых, поиск и разрешение — последовательные операции. Если поиск был успешным, а разрешение — нет, то чтобы вытащить перегрузку из базового класса компилятору придется повторить итерацию — снова сделать поиск и снова сделать разрешение.
Во-вторых, на мой взгляд, если разработчик сделал внутри наследника перегрузку с подходящей декларацией, но зачем-то затолкал ее в приватную секцию, то это больше похоже на ошибку, чем на злонамерение усложнить поддержку кода. Тут сообщивший об ошибке компилятор будет совершенно прав.
Спасибо! По поводу отсутствия объяснений, ПОЧЕМУ это так работает ответ достаточно традиционный — ограничения объема статьи. C++20 у меня пока в начальной стадии изучения, но уже чувствую, что придется поработать.
Я хочу выразить огромную благодарность за статью. Подписалась и очень жду продолжения. Это именно та информация, которая мне сейчас нужна. Спасибо!
Очень приятная статья. Осталось не ясным:
1) ADL — это требование языка или "рост так все компиляторы делают"? То же самое про SFINAE. (поясню: многие компиляторы очень вольно трактуют эти правила(?), при чём как старые этим грешат так и современные).
2) Из статьи понятно что модификаторы типа в обычных и шаблонных(?) функциях не играют роли при выборе перегрузки если тип указан "по значению". Не раскрыты на мой взгляд ситуации когда перегрузка функции идёт шаблонной функцией с параметром типа "ссылка на тип"/"указатель на тип".
А так — браво, правда очень познавательно и освежил свои знания.
Довольно крутой подход, по моему на уровне книги. Спасибо!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Перегрузка в C++. Часть I. Перегрузка функций и шаблонов