Это ошибка gcc 80871. Далее следует объяснение того, почему код сформирован правильно (и clang правильно решил, что t2
является custom_tuple<int>
).
Процесс выяснения того, что делать с
custom_tuple t2(42);
в основном включает в себя синтез набора функций и выполнение для них разрешения перегрузки. Подходящими кандидатами являются синтезированные функции из одного конструктора и руководства по выводу:
template <class... T, class... Args>
custom_tuple<T...> foo(Args... ); // the constructor
template <class... Args>
custom_tuple<Args...> foo(Args... ); // the deduction guide
С этого момента вы можете выбрать свое собственное приключение, основанное на вашей интерпретации того, что такое «конечный пакет параметров» в соответствии с [temp.arg.explicit]/3:
Замыкающий пакет параметров шаблона, не выведенный иным образом, будет преобразован в пустую последовательность аргументов шаблона. Если все аргументы шаблона могут быть выведены, все они могут быть опущены; в этом случае сам пустой список аргументов шаблона <>
также может быть опущен.
T...
не отстает
Этот случай легкий. У нас есть только один жизнеспособный кандидат (поскольку T...
не выводим) — кандидат на дедукцию. Мы выводим Args...
как {int}
, так что в итоге получаем custom_tuple<int>
.
T...
отстает
И gcc, и clang фактически считают вывод конструктора успешным. Итак, мы переходим к разрешению конфликтов в [over.match.best]:
Учитывая эти определения, жизнеспособная функция F1
определяется как лучшая функция, чем другая жизнеспособная функция F2
, если [...]
F1
и F2
являются специализациями шаблона функции, а шаблон функции для F1
является более специализированным, чем шаблон для F2
в соответствии с правилами частичного упорядочения, описанными в [temp.func.order], или, если не так,
F1
генерируется из руководства по дедукции ([over.match.class.deduct]), а F2
нет, или, если не так, [...]
В целях частичного упорядочения подходящие типы — это только те которые соответствуют параметрам функции, и нам разрешено игнорировать неиспользуемые параметры шаблона., поэтому ни один шаблон функции не считается более специализированным, чем другой.
Это оставляет нам возможность просто предпочесть руководство по дедукции, которое было самым простым шагом во всем этом процессе. Мы выводим Args...
как {int}
, так что в итоге получаем custom_tuple<int>
.
В любом случае, custom_tuple<int>
- правильное решение.
person
Barry
schedule
03.06.2017