Это не является следствием SFINAE или частичной упорядоченности, но связано с использованием параметров шаблона по умолчанию.Неофициально причина в том, что применение параметров шаблона по умолчанию происходит до поиска определений шаблона, включая возможные специализации.
Так что в приведенном выше случае код, который говорит is_default_constructable<int>
,фактически запрашивая создание экземпляра шаблона is_default_constructable<int, void>
после применения второго параметра по умолчанию.Затем рассматриваются возможные определения.
«Основное» определение шаблона явно совпадает и включено.Данная частичная специализация
template <typename T> struct is_default_constructable<T, decltype(T()) > : std::true_type {};
фактически определяет is_default_constructable<int, int>
, который не соответствует запрашиваемому is_default_constructable<int, void>
, поэтому специализация игнорируется, даже если замена удалась.Это оставляет первичное определение (наследующее false_type) как единственное жизнеспособное определение, поэтому оно выбрано.
Когда специализация имеет wrap<>
(или std::void_t<>
), чтобы заставить второй аргумент получить void
,специализация определяет is_default_constructable<int, void>
, которая соответствует запросу.Это определение (при условии, что замещение выполнено успешно, т. Е. T()
правильно сформировано) является более специализированным, чем первичное определение (согласно сверхсложным правилам упорядочения специализаций), поэтому оно выбрано.
В качестве отступления,вышеупомянутые наивные реализации, вероятно, не работают должным образом, когда T является ссылочным типом или в других угловых случаях, что является хорошей причиной для использования стандартных версий библиотеки всего этого.Люди из комитета по стандартам намного умнее меня и уже думали обо всех этих вещах.
Этот ответ и Этот ответ на вопросы, связанные с чем-то более подробныминформация, которая исправляет меня.
И, да, я не могу записать конструктивное, если предположить, что это даже слово.Что является еще одной веской причиной для использования стандартной библиотеки.