Допускают ли независимые аргументы шаблона по умолчанию шаблонов функций SFINAE?

Под «независимым» здесь я подразумеваю «независимый от любых других аргументов шаблона этого конкретного шаблона функции».

Отвечаяэтот вопросЯ думал, что нашел ответ, но, согласно @Johannes (в комментариях к моему ответу), я неправильно интерпретирую стандарт здесь. Возьмите следующий простой пример:

#include <type_traits>

template<class T>
struct X{
  template<class U = typename T::type>
  static void foo(int){}
  static void foo(...){}
};

int main(){
  X<std::enable_if<false>>::foo(0);
}

(Живая версия.)

Есть ли гарантия, что вышеперечисленные компилируются? GCC и Clang здесь не согласны, что можно увидеть в живой версии при переключении между ними. Интересно, что GCC принимает следующее:

#include <type_traits>

template<class T>
struct X{
  template<bool = T::f()>
  static void foo(int){}
  static void foo(...){}
};

struct Y{
  static bool f(){ return true; }
};

int main(){
  X<Y>::foo(0);
}

(Живая версия.)

Второй фрагмент будет только печататьfoo(int) еслиT содержитconstexpr статическая функцияf, Опять интересно, если полностью убратьf изY (или передать, скажем,int вместо этого) GCC жалуется на пропавшего участника, указывая, что он не допускает SFINAE, что противоречит предыдущему наблюдению. Clang принимает все варианты и применяет SFINAE, и мне интересно, гарантировано ли это стандартом.

(FWIW, MSVC с ноябрьским CTP обычно соглашается с Clang, но вылетает во втором фрагменте, если функция присутствует, вероятно, потому что у них нетconstexpr, Я отправил отчет об ошибкеВот.)

Ответы на вопрос(1)

Ваш ответ на вопрос