Argumentos de modelo padrão não dependentes de modelos de função permitem SFINAE?

Com "não dependente", quero dizer "não dependente de quaisquer outros argumentos de modelo desse modelo de função específico".

Enquanto respondeessa questão, Achei que encontrei a resposta, mas de acordo com @Johannes (nos comentários à minha resposta), estou interpretando mal o padrão aqui. Tome o seguinte exemplo simples:

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

(Versão ao vivo.)

Existe alguma garantia de que o acima compila? O GCC e o Clang discordam aqui, como pode ser visto na versão ao vivo ao alternar entre eles. Curiosamente, porém, o seguinte é aceito pelo 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);
}

(Versão ao vivo.)

O segundo trecho será impresso apenasfoo(int) E seT contém umconstexpr função estáticaf. Mais uma vez, curiosamente, se você remover completamentef deY (ou passe, digamos,int em vez disso), o GCC queixa-se de um membro ausente, indicando que não permite a SFINAE - o que é contraditório com a observação anterior. O Clang aceita todas as variações e aplica o SFINAE, e eu me pergunto se isso é o que é garantido pelo padrão.

(FWIW, MSVC com o Nov CTP geralmente concorda com o Clang, mas falha no segundo snippet se a função estiver presente, provavelmente porque eles não têmconstexpr. Eu enviei um relatório de bugAqui.)

questionAnswers(1)

yourAnswerToTheQuestion