Вы правы. Неявно сгенерированное руководство по выводам действительно будет похоже на то, которое вы написали. И вывод аргумента шаблона никогда не сможет вывести T
из него. Это действительно не вызовет проблем. Проблема заключается в предоставленных пользователем руководствах по выводам. Как это:
template <typename Iter>
X(Iter a, Iter b) -> X<typename Iter::value_type>;
Которые часто добавляются, чтобы разрешить вывод аргументов шаблона класса из итераторов . Это может привести к хаосу, если имя введенного класса не подавит вывод аргумента. Авторы, возможно, упустили необходимость добавить это руководство по выводам, чтобы продемонстрировать проблему.
Вот иллюстрация проблемы:
auto v = std::vector<int>{1, 2};
auto x1 = X<float>(begin(v), end(v));
auto x2 = x1.f(begin(v), begin(v));
Какой тип x2
? Если мы прочитаем определение шаблона класса, мы ожидаем, что оно будет X<float>
, как это было бы в C ++ 14, но если вычет аргумента шаблона класса не отключен, и мы добавим наше руководство по выводу, мы получим X<int>
!
Представьте себе существующие базы кода, в которых типы внезапно сместились после перехода на C ++ 17. Это было бы очень плохо.