¿Los argumentos de plantilla predeterminados no dependientes de las plantillas de función permiten SFINAE?

Con "no dependiente" aquí me refiero a "no dependiente de cualquier otro argumento de plantilla de esa plantilla de función específica".

Mientras respondeesta pregunta, Pensé que había encontrado la respuesta, pero según @Johannes (en los comentarios a mi respuesta), estoy interpretando mal el estándar aquí. Tomemos el siguiente ejemplo simple:

#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);
}

(Versión en vivo.)

¿Hay alguna garantía de que lo anterior compile? GCC y Clang no están de acuerdo aquí, como se puede ver en la versión en vivo al cambiar entre ellos. Curiosamente, sin embargo, GCC acepta lo siguiente:

#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);
}

(Versión en vivo.)

El segundo fragmento solo se imprimirá.foo(int) SiT contiene unaconstexpr función estáticaf. De nuevo, curiosamente, si eliminas completamentef desdeY (o pase, digamos,int en su lugar), GCC se queja de un miembro faltante, lo que indica que no permite SFINAE, lo que es contradictorio con la observación anterior. Clang toma todas las variaciones y aplica SFINAE, y me pregunto si eso es lo que garantiza la norma.

(FWIW, MSVC con el CTP de noviembre generalmente está de acuerdo con Clang, pero se bloquea en el segundo fragmento de código si la función está presente, probablemente porque no tienenconstexpr. He enviado un informe de erroraquí.)

Respuestas a la pregunta(1)

Su respuesta a la pregunta