Как работает эта вычет типа и разрешение перегрузки?

Код №1

#include <iterator>
#include <algorithm>
#include <iostream>
#include <vector>

template <typename container>
void sort(typename container::iterator beginning,
          typename container::iterator end)
{
    std::cout << "calling custom sorting function\n";
}

int main()
{
    std::vector<int> v{1, 2, 3};
    sort(v.begin(), v.end());
}

Wandbox.

Описание кода

Он будет вызывать функцию std::sort, которая найдена ADL. Хотя приведенный ниже код:

Код №2

#include <iterator>
#include <algorithm>
#include <iostream>
#include <vector>

template <typename Iterator>
void sort(Iterator beginning,
          Iterator end)
{
    std::cout << "calling custom sorting function\n";
}

int main()
{
    std::vector<int> v{1, 2, 3};
    sort(v.begin(), v.end());
}

Wandbox.

Вызывает неоднозначную ошибку перегрузки. Поэтому у меня есть два вопроса:

Вопросы

  1. Как container был выведен в код # 1?

    Из того, что я знаю, тип дедукции во время создания шаблона не может возвращаться через типы участников, чтобы найти вложенный (std::vector<int> в этом случае).

  2. Даже если он может отступить, почему он скомпилировался, не вызывая неоднозначную ошибку перегрузки?

Ответ 1

Как container был выведен в код # 1?

Он не может быть выведен во время вычитания аргумента шаблона из -за невыводимого контекста,

1) Спецификатор вложенного имени (все слева от оператора разрешения области видимости :: :) типа, который был задан с использованием идентификатора qualit:

Это означает, что ваш sort не будет рассматриваться для разрешения перегрузки вообще, тогда std::sort вызывается без двусмысленности.

Код №2 не имеет такой проблемы, и ваши sort и std::sort являются действительными кандидатами, а затем приводят к неоднозначной ошибке перегрузки.